<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    ivaneeo's blog

    自由的力量,自由的生活。

      BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
      669 Posts :: 0 Stories :: 64 Comments :: 0 Trackbacks

    #

    gcc編譯過(guò)程分為4個(gè)階段:(源代理*.c)
    .預(yù)處理(和頭文件*.h)
    .適當(dāng)編譯(生成目標(biāo)代理*.o)
    .匯編
    .鏈接(和引導(dǎo)代碼,庫(kù)代碼)
    posted @ 2005-08-04 22:00 ivaneeo 閱讀(581) | 評(píng)論 (0)編輯 收藏

    其他的調(diào)試選項(xiàng)包括-p和-pg,它們將剖析(profiling)信息加入二進(jìn)制文件中.這些信息對(duì)于找出代碼中的性能瓶頸以及開(kāi)發(fā)高性能的程序非常有 幫助.-p選項(xiàng)在代碼中加入prof程序能夠讀取的剖析符合信息,而-pg選項(xiàng)加入了GNU項(xiàng)目中prof的化身gprof能夠解釋的符合信息.-a選項(xiàng) 在代碼中加入代碼塊(比如函數(shù))累計(jì)使用的次數(shù).

    -save-temps選項(xiàng)可以保存在編譯過(guò)程中生成的中間文件,其中包括目標(biāo)文件和匯編代碼文件.

    如果你對(duì)編譯器到底花費(fèi)了多少時(shí)間來(lái)完成它的工作感興趣,可以考慮使用-Q選項(xiàng),這個(gè)選項(xiàng)讓gcc顯示編譯過(guò)程中碰到的每個(gè)函數(shù),并提供編譯器編譯每個(gè)函數(shù)所花時(shí)間的剖析信息.
    posted @ 2005-08-04 21:59 ivaneeo 閱讀(561) | 評(píng)論 (0)編輯 收藏

    $gcc -g hello.c -o hello
    $ls -l hello
    -rwxr-xr-x 1 kwall users 10275 May 21 23:27 hello

    $gcc -ggdb hello.c -o hello
    $ls -l hello
    -rwxr-xr-x 1 kwall users 8135 May 21 23:28 hello

    -g選項(xiàng)讓二進(jìn)制文件大小增長(zhǎng)到將近三倍,而-ggdb選項(xiàng)也讓其大小增加了一倍!盡管會(huì)使文件大小增長(zhǎng),仍然建議在執(zhí)行文件中包含標(biāo)準(zhǔn)的調(diào)試符合(使用-g選項(xiàng)創(chuàng)建),以便某些用戶在遇到問(wèn)題時(shí)可以調(diào)試你的代碼.
    posted @ 2005-08-04 21:58 ivaneeo 閱讀(1104) | 評(píng)論 (0)編輯 收藏

                              gcc優(yōu)化標(biāo)志
    選項(xiàng)                  作用
    -ffloat-store         禁止在CPU的寄存器中保存浮點(diǎn)變量的值.這能把CPU寄存器節(jié)省下來(lái)留作它用,而且可以防止產(chǎn)生過(guò)分精確但不必要的浮點(diǎn)數(shù).
    -ffast-math           產(chǎn)生浮點(diǎn)數(shù)學(xué)優(yōu)化,這能提高速度但違反了IEEE或ANSI/ISO標(biāo)準(zhǔn).如果程序不需要嚴(yán)格遵守IEEE規(guī)范,可在編譯浮點(diǎn)密集型的程序時(shí)考慮采用這一標(biāo)志
    -finline-functions    把所有的"簡(jiǎn)單"函數(shù)在調(diào)用它們的函數(shù)中就地展開(kāi).編譯器決定了什么是"簡(jiǎn)單"函數(shù).減少處理器與函數(shù)相關(guān)的開(kāi)銷是一種基本的優(yōu)化技術(shù)
    -funroll-loops        展開(kāi)所有能在編譯時(shí)確定重復(fù)次數(shù)的循環(huán)體.展開(kāi)循環(huán)體后每步循環(huán)都能省出幾條CPU指令,這樣大大減少了執(zhí)行時(shí)間
    -fomit-frame-pointer  如果函數(shù)不需要?jiǎng)t丟掉指針,該指針保存在CPU的一個(gè)寄存器中.因?yàn)槿サ袅嗽O(shè)置,保存和恢復(fù)幀指針?biāo)匦璧闹噶?所以加快了處理速度.
    -fschedule-insns      記錄可能暫停的指令,因?yàn)樗鼈冋诘群虻臄?shù)據(jù)不在CPU中
    -fschedule-insns2     執(zhí)行第二次指令重排序(類似于-fschedule-insns)
    -fmove-all-movables   把所有出現(xiàn)在循環(huán)體內(nèi)部但穩(wěn)定不變的計(jì)算移出循環(huán)體.這從循環(huán)體中去除了不必要的操作,加快了循環(huán)的整體運(yùn)算速度.

    內(nèi)聯(lián)和循環(huán)展開(kāi)技術(shù)都能夠大大提高程序的執(zhí)行速度,因?yàn)樗鼈兌急苊饬撕瘮?shù)調(diào)用和變量查找的開(kāi)銷,但付出的代價(jià)往往是大大增加了目標(biāo)或二進(jìn)制代碼的大小.

    一般而言,Linux程序員似乎愛(ài)用優(yōu)化選項(xiàng)-O2.
    posted @ 2005-08-04 21:57 ivaneeo 閱讀(1723) | 評(píng)論 (0)編輯 收藏

    使用gcc的-g和-ggdb選項(xiàng)在編譯后的程序中插入調(diào)試信息以方面調(diào)試會(huì)話過(guò)程.能夠用1,2或3來(lái)限定-g選項(xiàng)來(lái)指定產(chǎn)生多少調(diào)試信息.默認(rèn)的級(jí)別 是2(-g2),此時(shí)的產(chǎn)生的調(diào)試信息包括擴(kuò)展的符號(hào)表,行號(hào)以及局部或外部變量的信息.這些信息全部保存在二進(jìn)制文件里.3級(jí)調(diào)試信息包括所有的2級(jí)信 息和源代碼中定義的所有宏.相反,1級(jí)產(chǎn)生的信息只夠創(chuàng)建回溯(backtrace)和堆棧轉(zhuǎn)儲(chǔ)(stack dump)之用.

    回溯是指一個(gè)程序調(diào)用函數(shù)的歷史.堆棧轉(zhuǎn)儲(chǔ)是一個(gè)通常以原始的十六機(jī)制格式保存程序執(zhí)行環(huán)境內(nèi)容的列表,列表內(nèi)容主要是CPU寄存器和分配給程序的內(nèi)存.注意,1級(jí)調(diào)試不產(chǎn)生局部變量和行號(hào)的調(diào)試信息.
    posted @ 2005-08-04 21:57 ivaneeo 閱讀(2748) | 評(píng)論 (0)編輯 收藏

    計(jì)算pi的平方根
    /*
    *  pisqrt.c - Calculate the square of PI 100,000,000
    */
    #include <stdio.h>
    #include <math.h>

    int main(void)
    {
      double pi = M_PI; /* Defined in <math.h> */
      double pisqrt;
      long i;

      for(i = 0; i < 10000000; ++i) {
        pisqrt = sqrt(pi);
      }
      return 0;
    }

                                 pisqrt的執(zhí)行時(shí)間
    標(biāo)志/優(yōu)化                       平均執(zhí)行時(shí)間
    <none>                         5.43s
    -O1                            2.74s
    -O2                            2.83s
    -O3                            2.76s
    -ffloat-store                  5.41s
    -ffast-math                    5.46s
    -funroll-loops                 5.44s
    -fschedule-insns               5.45s
    -fschedule-insns2              5.44s

    這個(gè)例子說(shuō)明,除非對(duì)處理器的體系結(jié)構(gòu)非常了解或者知道某種特殊的優(yōu)化專門針對(duì)你的程序有影響,否則就應(yīng)該使用優(yōu)化選項(xiàng)-O.
    posted @ 2005-08-04 21:56 ivaneeo 閱讀(511) | 評(píng)論 (0)編輯 收藏

    pgcc的主要好處是它對(duì)Pentium處理器的優(yōu)化較好.
    posted @ 2005-08-04 21:56 ivaneeo 閱讀(435) | 評(píng)論 (0)編輯 收藏

    1.關(guān)于可移植性
    #ifdef __STRICT_ANSI__
    /* use ANSI/ISO C only here */
    #else
    /* use GNU extensions here */
    #endif
    如果用戶或是ANSI兼容的編譯器定義了__STRICT_ANSI__宏,則表明需施加ANSI兼容的環(huán)境,并編譯#ifdef語(yǔ)句塊的第一部分代碼.否則,編譯#else后面的代碼.
    2.GNU擴(kuò)展
      gcc使用long long 類型來(lái)提供64位儲(chǔ)存單元:
      long long long_int_var;
    內(nèi)聯(lián)函數(shù)
      要使用內(nèi)聯(lián)函數(shù),需在函數(shù)的返回類型前面插入關(guān)鍵字inline,如下面的代碼片段所示,還要在編譯時(shí)使用-O優(yōu)化選項(xiàng).
      inline void swap(int *a, int *b)
      {
        int tmp = *a;
        *a = *b;
        *b = tmp;
      }
    函數(shù)和變量屬性
      關(guān)鍵字attribute通過(guò)向gcc指明有關(guān)代碼的更多信息來(lái)幫助代碼優(yōu)化工作進(jìn)行得更好.例如,標(biāo)準(zhǔn)庫(kù)函數(shù)exit和 abort都不返回調(diào)用它們的函數(shù).編譯器如果知道它們不返回就能生成效率稍高的代碼.當(dāng)然用戶程序也能定義不返回的函數(shù).gcc允許為這些函數(shù)指定 noreturn屬性,作為編譯器在優(yōu)化該函數(shù)時(shí)的提示.
      
    例如,假設(shè)有個(gè)沒(méi)有返回的函數(shù)die_on_error.為了使用函數(shù)屬性,可以在函數(shù)聲明后面加上__attribute__((attribute_name)).于是函數(shù)die_on_error的聲明如下:
      void die_on_error(void) __attribute__ ((noreturn));
    函數(shù)還和平常一樣來(lái)定義:
      #include <stdlib.h>
      void die_on_error(void)
      {
        /* your code here */
        exit(EXIT_FAILURE);
      }

    也可以對(duì)變量指定屬性.例如,aligned屬性指示編譯器在為變量分配內(nèi)存空間時(shí)按指定字節(jié)數(shù)對(duì)齊邊界.下列語(yǔ)句:
      int int_var __attribute__ ((aligned 16)) = 0;
    使gcc讓變量int_var的邊界按16字節(jié)對(duì)齊.packed屬性告訴gcc為變量或結(jié)構(gòu)分配最小的內(nèi)存空間.

    如果想要關(guān)閉對(duì)未用變量發(fā)出的所有警告,那么可以對(duì)變量使用unused屬性,它告訴編譯器該變量不準(zhǔn)備使用.下面的變量聲明會(huì)消除警告:
      float big_salary __attribute__ ((unused));

    使用case區(qū)間
    case區(qū)間是一個(gè)非常有用的擴(kuò)展.其語(yǔ)法如下:
      case LOWVAL ... LOWVAL:
    注意,在省略號(hào)前后必須有空格.在switch語(yǔ)句中,case區(qū)間指定了落在LOWVAL和HIVAL區(qū)間內(nèi)的那些整數(shù)值.例如:
      switch(int_var) {
      case 0 ... 2:
        /* your code here */
        break;
      case 3 ... 5:
        /* more code here */
        break;
      default:
        /* default code here */
      }

    構(gòu)造函數(shù)名稱
      把函數(shù)名用作字符串是GNU的擴(kuò)展,它能極大地簡(jiǎn)化調(diào)試工作.gcc預(yù)先定義了變量__FUNCTION__為當(dāng)前函數(shù)(控制流程當(dāng)前所在的位置)的名字,就好像它被寫在源代碼里去了一樣.

    使用__FUNCTION__變量
    /*
    *  showit.c - Illustrate using the __FUNCTION__ variable
    */
    #include <stdio.h>

    void foo(void);

    int main(void)
    {
      printf("The current function is %s\n", __FUNCTION__);
      foo();
      return 0;
    }

    void foo(void)
    {
      printf("The current function is %s\n", __FUNCTION__);
    }
    posted @ 2005-08-04 21:55 ivaneeo 閱讀(616) | 評(píng)論 (0)編輯 收藏

    下面是定義變量的一般方法:
      VARNAME=some_text [...]
    把變量用括號(hào)起來(lái),并在前面加上"$"符號(hào),就可以引用變量的值:
      $(VARNAME)
    變量一般都在makefile的頭部定義,并且,按照慣例,所有的makefile變量都應(yīng)該大寫.

    在makefile中使用變量
    OBJS = howdy.o helper.o
    HDRS = helper.h
    howdy: $(OBJS) $(HDRS)
        gcc $(OBJS) -o howdy
    helper.o: helper.c $(HDRS)
        gcc -c helper.c
    howdy.o: howdy.c
        gcc -c howdy.c
    hello: hello.c
        gcc hello.c -o hello
    all: howdy hello
    clean:
        rm howdy hello *.o

    make使用兩種變量:遞歸展開(kāi)變量和簡(jiǎn)單展開(kāi)變量.遞歸展開(kāi)變量在引用時(shí)逐層展開(kāi),即如果在展開(kāi)式中包含了對(duì)其他變量的引用,則這些變量也將被展開(kāi),直到?jīng)]有需要展開(kāi)的變量為止,這就是所謂的遞歸展開(kāi).

    考慮下面的變量定義:
      CC = gcc
      CC = $(CC) -o
    CC在被引用時(shí)遞歸展開(kāi),從而陷入一個(gè)無(wú)限循環(huán)中:CC將展開(kāi)為$(CC)的值,從而永遠(yuǎn)也讀不到-o選項(xiàng).

    為了避免這個(gè)問(wèn)題,可以使用簡(jiǎn)單展開(kāi)變量.與遞歸展開(kāi)變量在引用時(shí)展開(kāi)不同,簡(jiǎn)單展開(kāi)變量在定義處展開(kāi),并且只展開(kāi)一次,從而取消了變量的嵌套引用.在定義時(shí),其語(yǔ)法與遞歸展開(kāi)變量有細(xì)微的不同:
      CC := gcc -o
      CC += -O2
    第一個(gè)定義使用":="設(shè)置CC的值為gcc -o, 第二個(gè)定義使用"+="在前面定義的CC后附加了-O2,從而CC最終的值是gcc -o -O2.

    除用戶定義變量外,make也允許使用環(huán)境變量,自動(dòng)變量和預(yù)定義變量.使用環(huán)境變量非常簡(jiǎn)單.在啟動(dòng)時(shí),make讀取已定義的環(huán)境變量,并且創(chuàng)建與之同名同值的變量.但是,如果makefile中有同名的變量,則這個(gè)變量將取代與之相應(yīng)的環(huán)境變量,所以應(yīng)當(dāng)注意這一點(diǎn).

                                    自動(dòng)變量
    變量                          說(shuō)明
    $@                            規(guī)則的目標(biāo)所對(duì)應(yīng)的文件名
    $<                            規(guī)則中的第一個(gè)相關(guān)文件名
    $^                            規(guī)則中所有相關(guān)文件的列表,以空格為分界符
    $?                            規(guī)則中日期新于目標(biāo)的所有相關(guān)文件的列表,以空格為分隔符
    $(@D)                       目標(biāo)文件的目錄部分(如果目標(biāo)在子目錄中)
    $(@F)                       目標(biāo)文件的文件名部分(如果目標(biāo)在子目錄中)

                      用于文件名和標(biāo)志的預(yù)定義變量
    變量                     說(shuō)明
    AR                       歸檔維護(hù)程序,默認(rèn)值=ar
    AS                       匯編程序,默認(rèn)值=as
    CC                       C編譯程序,默認(rèn)值=cc
    CPP                       C預(yù)處理程序,默認(rèn)值= cpp
    RM                       文件刪除程序,默認(rèn)值="rm -f"
    ARFLAGS                   傳給歸檔維護(hù)程序的標(biāo)志,默認(rèn)值=rv
    ASFLAGS                   傳給匯編程序的標(biāo)志,沒(méi)有默認(rèn)值
    CFLAGS                   傳給C編譯器的標(biāo)志,沒(méi)有默認(rèn)值
    CPPFLAGS                 傳給C預(yù)處理程序的標(biāo)志,沒(méi)有默認(rèn)值
    LDFLAGS                   傳給鏈接程序(ld)的標(biāo)志,沒(méi)有默認(rèn)值
    posted @ 2005-08-04 21:54 ivaneeo 閱讀(277) | 評(píng)論 (0)編輯 收藏

    下面解釋make是如何工作的:當(dāng)遇到目標(biāo)體clean時(shí),make先查看其是否有依賴體,因?yàn)閏lean沒(méi)有依賴體,所以make認(rèn)為目標(biāo)體是最新的而不執(zhí)行任何操作.為了編譯這個(gè)目標(biāo)體,必須輸入make clean.

    然而,如果恰巧有一個(gè)名為clean的文件存在,make就會(huì)發(fā)現(xiàn)它.然后和前面一樣,因?yàn)閏lean沒(méi)有依賴體文件,make就認(rèn)為這個(gè)文件是最新的而不會(huì)執(zhí)行相關(guān)命令.為了處理這類情況,需要使用特殊的make目標(biāo)體.PHONY. .PHONY的依賴體文件的含義和通常一樣,但是make不檢查是否存在有文件名和依賴體中的一個(gè)名字相匹配的文件,而是直接執(zhí)行與之相關(guān)的命令.在使用了.PHONY之后,前面的例子如下:
    howdy: howdy.o helper.o helper.h
        gcc howdy.o helper.o -o howdy
    helper.o: helper.c helper.h
        gcc -c helper.c
    howdy.o: howdy.c
        gcc -c howdy.c
    hello: hello.c
        gcc hello.c -o hello
    all: howdy hello
    .PHONY : clean
    clean:
        rm howdy hello *.o
    posted @ 2005-08-04 21:52 ivaneeo 閱讀(334) | 評(píng)論 (0)編輯 收藏

    僅列出標(biāo)題
    共67頁(yè): First 上一頁(yè) 56 57 58 59 60 61 62 63 64 下一頁(yè) Last 
    主站蜘蛛池模板: 无人在线观看免费高清| 亚洲美日韩Av中文字幕无码久久久妻妇| 青青草97国产精品免费观看| 亚洲美女精品视频| 一本久久a久久精品亚洲| 国产成人免费网站在线观看| 亚洲毛片免费视频| 日韩免费无码一区二区三区| 久久久精品视频免费观看| 亚洲成av人片在线天堂无| 亚洲一级毛片在线播放| 亚洲AV无码国产精品色午友在线| 亚洲精品天堂成人片?V在线播放| 日韩精品无码人妻免费视频 | 免费**毛片在线播放直播| 成年女人毛片免费观看97| 久久国产色AV免费看| 免费黄网站在线看| 中出五十路免费视频| 一级黄色免费大片| 色屁屁在线观看视频免费| 亚洲美国产亚洲AV| 亚洲午夜无码久久久久小说| 亚洲伦理一二三四| 亚洲国产综合第一精品小说| 亚洲高清日韩精品第一区| 亚洲国产成人久久综合一| 人人狠狠综合久久亚洲婷婷| 亚洲人成网亚洲欧洲无码久久 | 国产精品免费久久| 亚洲视频在线免费| jizz免费在线观看| 国产性生大片免费观看性| 国色精品va在线观看免费视频| 国产免费区在线观看十分钟| 国产精品无码永久免费888| 国产精品hd免费观看| 三年在线观看免费观看完整版中文| 国产裸体美女永久免费无遮挡| 两个人日本免费完整版在线观看1| 美女被免费网站91色|