J

2004 | 08 | 09 | 10 | 11 | 12 |
2005 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 12 |
2008 | 01 | 02 | 04 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 01 |

ホーム

日記内の"morihyphen.hp.infoseek.co.jp"へのリンクは切れてます。必要な場合はお手数ですが int.main.jp へ書き換えをお願いします。

TODO: ファイル名確認を忘れないこと > 自分

twitter

 | 

2006-08-16

大阪人…というように、今留守であることを書いておくのは、セキュリティの観点からよろしくないのではという気が。

[] builtin_expect

http://www.pqrs.org/~tekezo/nikki/2006/08/15.html#y2006m08d15c1p2

なんだか面白そうなので調査。


まず、予想としては、中間形式での最適化時に__builtin_expectがただの関数扱いされて、最適化を控えているのではないかと思われます。

  • if ( bi == NULL ) の場合、副作用が無いとわかるので、なんか最適化をする
  • if ( __builtin_expect( bi==NULL, 0 ) ) は、中間形式の状態では、副作用があるか無いかわからんので最適化を控える

と、そういう感じではないかと。この場合だと、if ( bi == NULL )のほうは、ループ用の最適化をしてて、__builtin_expectのほうはそれをやってない感じですかね。


ループが変形してるのは、ループ脱出条件の最適化としては、結構簡単にできる有名な奴ではないかと思われます。

while ( cond ) {
	....
	loop_body;
	....
}

ていうのは、普通にコンパイルすれば

	...

loop_begin:
	cmp	cond
	jcc	exit

loop_body:
	... ( ループ内処理 )

	jmp	loop_begin

exit:
	...

こんな感じ。ですが、これを

	jmp	loop_cond
loop_body:
	... ( ループ内処理 )

loop_cond
	cmp	cond
	jcc	loop_body # 条件ジャンプを後ろにする

exit:
	...

こんな風にしてやれば、ループ中の分岐が「条件分岐 + 無条件」から、「条件分岐一個」に減らせます。

と、思ったけど、よく見てみたら、continueがあるのでなんか違うような気がしてきましたが、「通常時」のほうの、eaeの前の命令が、「b ec6」もしくは、「NULLチェックしてループ処理飛ばす」みたいな感じだと、なんかそれに近いことをやってるんだと思います。(適当)


ただ、この最適化をやるには、「どこらへんがループで、どれが脱出条件か」というのを見つけないというのがあって、__builtin_expectを使ったほうは、多分、そこらへんができてないのではないかと。


対処法としては、手元にあった、GCC4.1の場合、

for ( ; __builtin_expect(nanika!=NULL,1); ) {
	// ループ処理
}

こんなふうにしてやれば、Cフロントエンドが「forループ→中間形式」変換時に上のループ最適化をやってくれるようなのでなんとかなるようです。


(うーん…ていうことは、多少汚くなっても無理矢理forとかwhile使ったほうがいいってことなのか…?僕はbreak使うほうが好きなんだけど…)


あと、__builtin_expectは、PowerPCみたいな条件分岐に命令に直接分岐ヒント付けられるCPUじゃないとあんまり効果が無いような気がしたんですが、そこらへんは、誰か偉い人が。

トラックバック - http://d.hatena.ne.jp/w_o/20060816
 |