インラインアセンブラで最適化が阻害される例(汗
__forceinline unsigned int _BitScanReverse2( unsigned int a ) { __asm { bsr eax, dword ptr a } } void main() { unsigned int _c_=5; unsigned int _index_; while( _c_ ) { _index_ = _BitScanReverse2( _c_ ); _c_ ^= 1<< _index_; \ } }
stacksさんに、
こう書くよりLS3600さんの書き方の方が速いとのことで
100万回で確認してもベンチマークに差が無かったんですが、
アセンブラにしてみると
; Line 11 push ecx ; Line 20 mov DWORD PTR __c_$[esp+4], 5 npad 8 $LL2@main: ; Line 24 bsr eax, DWORD PTR __c_$[esp+4] ; Line 25 mov edx, 1 mov ecx, eax shl edx, cl xor DWORD PTR __c_$[esp+4], edx jne SHORT $LL2@main ; Line 28 xor eax, eax pop ecx ret 0 _main ENDP
うわーメモリーアクセスしてるよー
インラインアセンブラでeaxを使うことを強制しているので、
レジスタ割り当ての最適化が利かなかったっぽいですね。
「dword ptr a」でわざわざメモリを読めって指示してるし(^^;
組み込み命令を使えば、きちんと最適化されるのに、
まさにインラインアセンブラの落とし穴にどっぷりはまってます(^^;
ベンチマークで差が出なかったのが謎。その他のコードが非効率なことをしているので
そこで埋もれたのかも。
指し手を32bitPackにすれば、二倍速で90万/secは出ると思うので、
このへんの差が利いて来るのかもしれない。