使用特定的GCC參數可以使編譯出的程式執行效率有較大提升。具體如下:
1、優化原理:
在編譯程式時,借助參數傳遞的方法,使用與系統CPU相比對的gcc參數,編譯出的程式就是為系統CPU而進行特定優化過的,因而執行速度和效率都會是最好。
2、注意事項
(1) 經過大量測試發現,在RedHat, CentOS系統中通常隻能通過參數傳遞的方法進行編譯優化,當然,如果願意并且能夠修改程式的MakeFile也可以達到這一效果,隻不過比較複雜,工 作量較大。其他在網上廣為流傳的方法(例如:直接通過.bashrc, /etc/profile聲明參數系統變量、寫入/etc/make.conf等)經過測試均沒有效果。
(2) 對于Gentoo Linux或FreeBSD可以通過修改/etc/make.conf添加參數的方法來實作,而不必使用參數傳遞法。
3、優化步驟:
(1)确定系統CPU類型:
# cat /proc/cpuinfo | grep "model name"
執行後會看到系統中CPU的具體型号,記下CPU型号。
(2)使用參數傳遞方法進行編譯:(以Pentium4 CPU為例)
此處以編譯Apache為例說明如何使用參數傳遞:
# tar xzvf httpd-2.0.55.tar.gz
# cd httpd-2.0.55
CHOST="i686-pc-linux-gnu" \
CFLAGS="-O3 \
-msse2 \
-mmmx \
-mfpmath=sse \
-mcpu=pentium4 \
-march=pentium4 \
-pipe \
-fomit-frame-pointer" \
CXXFLAGS="-O3 \
-funroll-loops \
./configure ......
# make
# make install
這樣就通過函數傳遞方法實作了編譯優化。下面對其中的一些參數進行具體說明:
-O3:相對于-O、-O1、-O2,-O3開啟了所有GCC支援的優化特性;
-msse2:開啟CPU所支援的sse2指令集;
-mmmx:參考-msse2
-mfpmath=sse:為指定指令集生成浮點運算特性(優化浮點運算功能);
-mcpu:指定CPU型号;
-march:指定CPU型号,基本同-mcpu,GCC根據-march設定的CPU型号決定在生成代碼時可以使用哪些種類的指令。(注意!-march參數在某些CPU型号中不可用!)
-pipe:使用管道(pipe)方法替代臨時檔案方法在編譯的不同階段之間進行通訊。
附:常見CPU優化參數
386:
CHOST="i386-pc-linux-gnu"
CFLAGS="-march=i386 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=i386 -O3 -pipe -fomit-frame-pointer"
486:
CHOST="i486-pc-linux-gnu"
CFLAGS="-march=i486 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=i486 -O3 -pipe -fomit-frame-pointer"
Pentium (Intel):
CHOST="i586-pc-linux-gnu"
CFLAGS="-march=pentium -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=pentium -O3 -pipe -fomit-frame-pointer"
Pentium MMX (Intel):
CFLAGS="-march=pentium-mmx -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=pentium-mmx -O3 -pipe -fomit-frame-pointer"
Pentium PRO (Intel):
CHOST="i686-pc-linux-gnu"
CFLAGS="-march=pentiumpro -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=pentiumpro -O3 -pipe -fomit-frame-pointer"
Pentium II (Intel):
CFLAGS="-march=pentium2 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=pentium2 -O3 -pipe -fomit-frame-pointer"
Celeron (Intel):
Pentium III (Intel):
CFLAGS="-march=pentium3 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=pentium3 -O3 -pipe -fomit-frame-pointer"
Celeron2 (Intel):
Celeron (Willamette-Intel):
CFLAGS="-march=pentium4 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=pentium4 -O3 -pipe -fomit-frame-pointer"
Pentium 4 (Intel):
K6 (AMD):
CFLAGS="-march=k6 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=k6 -O3 -pipe -fomit-frame-pointer"
K6-2 (AMD):
CFLAGS="-march=k6-2 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=k6-2 -O3 -pipe -fomit-frame-pointer"
K6-3 (AMD):
CFLAGS="-march=k6-3 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=k6-3 -O3 -pipe -fomit-frame-pointer"
Athlon (AMD):
CFLAGS="-march=athlon -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=athlon -O3 -pipe -fomit-frame-pointer"
Athlon-tbird, aka K7 (AMD):
CFLAGS="-march=athlon-tbird -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=athlon-tbird -O3 -pipe -fomit-frame-pointer"
Athlon-tbird XP (AMD):
CFLAGS="-march=athlon-xp -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=athlon-xp -O3 -pipe -fomit-frame-pointer"
Athlon 4(AMD):
CFLAGS="-march=athlon-4 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=athlon-4 -O3 -pipe -fomit-frame-pointer"
Athlon XP (AMD):
Athlon MP (AMD):
CFLAGS="-march=athlon-mp -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=athlon-mp -O3 -pipe -fomit-frame-pointer"
603 (PowerPC):
CHOST="powerpc-unknown-linux-gnu"
CFLAGS="-O3 -pipe -fomit-frame-pointer -fsigned-char"
CXXFLAGS="-O3 -pipe -fomit-frame-pointer -fsigned-char"
603e (PowerPC):
604 (PowerPC):
604e (PowerPC):
750 aka as G3 (PowerPC):
CFLAGS="-mcpu=750 -O3 -pipe -fomit-frame-pointer -fsigned-char"
CXXFLAGS="-mcpu=750 -O3 -pipe -fomit-frame-pointer -fsigned-char"
7400, aka G4 (PowerPC):
CFLAGS="-mcpu=7400 -O3 -pipe -fomit-frame-pointer -fsigned-char -maltivec"
CXXFLAGS="-mcpu=7400 -O3 -pipe -fomit-frame-pointer -fsigned-char -maltivec"
7450, aka G4 second generation (PowerPC):
CFLAGS="-mcpu=7450 -O3 -pipe -fomit-frame-pointer -fsigned-char -maltivec"
CXXFLAGS="-mcpu=7450 -O3 -pipe -fomit-frame-pointer -fsigned-char -maltivec"
PowerPC (If you don't know which one):
Sparc:
CHOST="sparc-unknown-linux-gnu"
CFLAGS="-O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-O3 -pipe -fomit-frame-pointer"
Sparc 64:
CHOST="sparc64-unknown-linux-gnu"