« [Gentoo] NPTL (Native POSIX Threading Library)を有効にしてみようか… | トップページ | [Tips] Gentoo `Debian' Linux化のその後 (追加情報) »

2006年2月 6日 (月)

[Gentoo Tips] CFLAGSの最適化オプションを探究してみる

  以前、SHIMAさんトコを見ていたら「CFLAGS、CXXFLAGS、CHOSTの内容」の中で、

2)Pentium-M 1.4G,i855GM+ICH4M チップセット,gentoo-dev-sources使用マシン
CFLAGS="-O3 -march=
i686 -fomit-frame-pointer -funroll-loops -fforce-addr -pipe"
CXXFLAGS="${CFLAGS}"
CHOST="i686-pc-linux-gnu"

と、書かれていた。「-funroll-loopsオプションと -fforce-addrオプション?、何処かで見たけど意味を知らないなぁ~」と…(^^;。

  ところで、手元には FMV-BIBLO LOOX S9/70 (Crusoe TM5500 700MHz)がある。これはメインマシン FMV-BIBLO LOOX T70Eが壊れた等の使えなくなった時のバックアップマシンで、数年前にソフマップで中古で買い求めた。その時、Librettoと比較したのだが、HDDが 20GB vs 30GBで「また富士通かよぉ(^◇^;」と一人苦笑いしながら買ったのを覚えている。
  バックアップマシンだから、LOOX S9/70の出番は普段は無い。最近では LOOX T70Eの CPUファンの修理時に一週間位使った程度…(持ってて良かった)。という事で、Linuxの実験マシンに使っちゃえと(^^;。

でも、Crusoe TM5500の最適化オプションってなんなのさ?
  Gentoo Linuxの場合、/etc/make.confの CFLAGS/CXXFLAGSへの指定が重要。例えば、i586マシン上で「-march=i686」なんて指定してしまうと、動かないバイナリの一丁上がりになってしまう(^◇^;。
  Crusoeマシンと SHIMAさんトコのオプションが気になっていたので、併せてチト調べてみた。

-march=xxx には何が指定出来るのか?
  これは gccのバージョンによってオプションが違うだろうから manしてみた。gcc-3.4.4の該当部分が以下だが、例えば私の LOOX T70Eは Pentium-M。Pentium-Mにはちゃんと「pentium-m」という指定があることが判る。
  悩むのは Celeronだろうか?。その場合、「Safe flags to use for gentoo-1.4」が参考になる。manの結果に追記しておく。

i386
  Original Intel's i386 CPU.

i486
  Intel's i486 CPU.  (No scheduling is implemented for this chip.)

i586, pentium
  Intel Pentium CPU with no MMX support.

pentium-mmx
  Intel PentiumMMX CPU based on Pentium core with MMX instruction set support.

i686, pentiumpro
  Intel PentiumPro CPU.

pentium2
  Intel Pentium2 CPU based on PentiumPro core with MMX instruction set support.
  * Celeron (Mendocino), aka Celeron1 (Intel)

pentium3, pentium3m
  Intel Pentium3 CPU based on PentiumPro core with MMX and SSE instruction set support.
  * Celeron (Coppermine) aka Celeron2 (Intel)

pentium-m
  Low power version of Intel Pentium3 CPU with MMX, SSE and SSE2 instruction set support.  Used by Centrino notebooks.

pentium4, pentium4m
  Intel Pentium4 CPU with MMX, SSE and SSE2 instruction set support.
  * Celeron (Willamette?) (Intel)

prescott
  Improved version of Intel Pentium4 CPU with MMX, SSE, SSE2 and SSE3 instruction set support.

nocona
  Improved version of Intel Pentium4 CPU with 64-bit extensions, MMX, SSE, SSE2 and SSE3 instruction set support.

k6
  AMD K6 CPU with MMX instruction set support.

k6-2, k6-3
  Improved versions of AMD K6 CPU with MMX and 3dNOW! instruction set support.

athlon, athlon-tbird
  AMD Athlon CPU with MMX, 3dNOW!, enhanced 3dNOW! and SSE prefetch instructions support.

athlon-4, athlon-xp, athlon-mp
  Improved AMD Athlon CPU with MMX, 3dNOW!, enhanced 3dNOW! and full SSE instruction set support.

k8, opteron, athlon64, athlon-fx
  AMD K8 core based CPUs with x86-64 instruction set support.  (This supersets MMX, SSE, SSE2, 3dNOW!, enhanced 3dNOW! and 64-bit instruction set extensions.)

winchip-c6
  IDT Winchip C6 CPU, dealt in same way as i486 with additional MMX instruction set support.

winchip2
  IDT Winchip2 CPU, dealt in same way as i486 with additional MMX and 3dNOW!  instruction set support.

c3
  Via C3 CPU with MMX and 3dNOW!  instruction set support.  (No scheduling is implemented for this chip.)

c3-2
  Via C3-2 CPU with MMX and SSE instruction set support.  (No scheduling is implemented for this chip.)

それで、Crusoe向けの指定は?
  しかし、Crusoe向けの指定が無い…(?_?)。検索していくと 2001年まで遡るが、i686でいいらしい…。

o AZURE Diary 2003-03 - 2003.03.07
o 凹日記 in June, 2002 -
Jun.5,2002 (Wed)
o
Aprovechar la potencia de nuestro procesador x86 (2001)

が、う~む、

AZURE Diary 2003-03 - 2003.03.07 より
  もっとも-march=i686は納得できないなあ。crusoeには MTRRも i686 PREFETCHもないらしいので、動かないやつがでてくる可能性があると思うだ。

が気になる。
  が、プリフェッチは関係あるのだろうか?。プリフェッチと聞くとデータかコードのどっちかの先読みなんだろうけど、先読みしないのはコードに関係なさそうに思えるが…。
  MTTRについては「MTRR機能を使って Xの描画を高速化させたい」を読むと、チェックしてサポートされてなければカーネルの設定で有効にしなければ良さそうに思える。ところで、この MTTRは面白そうだ。あとで試してみよう(笑)。

  以上、ツラツラ考えるに、WindowsXPは少なくとも i686以上に最適化されて出荷されている筈…(最小動作環境は何処に書かれているのだろう)。それで問題が無いのだから、i686で問題無いと推察できる。
  実際、「Gentoo Linux on a Lifebook P-2040」でも、i686で動いている様であるし、検索した範囲では問題はレポートされていない…。

  Crusoeには -march=i686にしてみよっと。

その他の最適化オプションは?
  man gccとやると延々と表示されるので、今度は検索で調べてみた。「-funroll-loops -fforce-addr」をキーワードで調べると、T.Okayamaさんの「2004年04月分」の日記 - 2004年04月24日(土)「[comp] Gentoo概論」には、

CFLAGS="-O3 -pipe -fomit-frame-pointer -funroll-loops -fprefetch-loop-arrays -falign-functions=4 -fforce-addr -march=pentium3 -msse2 -mfpmath=sse"

と、さらにオプションが追加されており、

こんな感じに設定しています。ええ、あくまでもひかえめ。私けっこう遠慮がちな人なんですよ。

っと、評されているが、「遠慮がち…」ってのは冗句なんだろう(^^;。ちなみにその他の検索しても、この設定が一番濃い最適化の模様…(すごいな…)。

  さて、これらの意味は Interface誌が詳しい。元は gccのマニュアルからなのだろうが、かい摘んで引用すると、

Interface誌 フリーソフトウェア 徹底活用講座

o -fomit-frame-pointer
 このオプションを付加すると,フレーム・ポインタを必要としない関数の場合,フレーム・ポインタをレジスタにもちません.これにより,フレーム・ポインタをセーブ,設定,リストアする命令をなくすことができます.結果として多くの関数で利用可能なレジスタが一つ増えます.問題はGDBによるデバッグが不可能になってしまう点です.

o -funroll-loops
 ループ展開最適化を実行します.これは,コンパイル時か実行時に繰り返し回数が決められるループにしか行われません.
  -funroll-loopsは,前述の -fstrength-reduceと -frerun-cse-after-loopを含みます.

o -fprefetch-loop-arrays
 ターゲット・マシンがサポートしているならば,大量のデータ読み込みの際に先読みを行います.このとき,オプション-fstrength-reduceを付加しないと効果がありません.

o -fstrength-reduce
 ループの強度削減と繰り返し変数の削除の最適化を実行します.ループの外に出せる計算は外に出して,ステップ数を減らします.

o -falign-functions=4
 関数の境界そろえを行います.-falign-functions=32と指定すると関数を32バイト境界に配置します.-falign-functionsを指定するとマシンに依存するデフォルト値が設定されます.

o -fforce-addr
 メモリ中のアドレス定数を,それについて算術演算を行う前にレジスタにコピーします.処理速度が多少速くなる場合があります.
 メモリ中の数値を演算するよりレジスタに格納された数値を演算するほうがもちろん速くなります.このオプションは試してみる価値があると思います.

その他気になるオプションは、

o -fschedule-insns
 ターゲット・マシン上でこのフラグがサポートされている場合,必要なデータを利用可能になるまで待つことによる実行の遅延を防ぐために,命令の順番の変更を行います.これは遅い浮動小数点命令やメモリ読み込み命令の実行において,それらの結果を必要とする命令の前にほかの命令を詰め込みます.

o -floop-optimize
 ループの最適化を実行します.ループ内部の定数式を移動させたり,出口テスト条件を単純化したり,演算子の強さの低減を行い,ループの展開を行います.

があるのだが、T.Okayamaさんの指定でこれらも有効になる模様。

それで?
  さて、カリカリチューンを試してみますか…。が、glibcとか kernelのビルドでは /etc/make.confの設定を参照してなくて、-O2 だけでビルドされている雰囲気…。チト、気に入らない。安全に振って無視する様にしているのだろうか?。これらを変えるのはどうするのだろう?。

|

« [Gentoo] NPTL (Native POSIX Threading Library)を有効にしてみようか… | トップページ | [Tips] Gentoo `Debian' Linux化のその後 (追加情報) »

コメント

はじめまして、CFLAGSのオプション検索しててここに辿り着いた者です。
> glibcとか kernelのビルドでは /etc/make.confの設定を参照してなくて、-O2 だけでビルドされている雰囲気…。
これについてなんですが、カーネル、glibc、gccあたりはCFLAGSを指定すると構築時におかしな振る舞いをする、というのをLFS関連のドキュメントで見たことがあります。この問題を回避するために-O2でビルドされているものとおもわれます。
ただ、うちの環境ではglibcもgccも"-Os -funroll-loop -march=k8"を指定しましたが無事ビルドされ、glibcについては至極安定しています。gccについてはコンパイラ内部のエラーでこけることがたまにあるようですが、CVSを使用したので単純に最適化フラグが原因でクラッシュしている、とは結びつけ難い状態です。ひょっとすると新しめの環境では改善された問題なのかもしれません。
うちはgentooは使っていないので詳しくはわかりませんが、単に/etc/make.confを食べてくれないだけなら環境変数を自分で設定する、gccにエイリアスをかける、Makefile又はautomake.amに直で書くといった方法で強引にCFLAGSを設定できるかもしれません。

投稿: Fadis | 2006年3月 1日 (水) 18時27分

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/55683/8538088

この記事へのトラックバック一覧です: [Gentoo Tips] CFLAGSの最適化オプションを探究してみる:

« [Gentoo] NPTL (Native POSIX Threading Library)を有効にしてみようか… | トップページ | [Tips] Gentoo `Debian' Linux化のその後 (追加情報) »