プロファイリング日記

max, min 関数の最適化と x86 の cmov 命令 - yuyarinの日記について光成さんが「このままだと最適化オプションをつけたら0になるんじゃないか」と言っていたので自分で最適化オプションをつけても大丈夫なコードを書いて試してみた。VS2008, WinXP, Core2 @ 2.4GHz。おおざっぱにAが9クロック、Bが5クロックくらいで、Cが4.6クロックくらい?BとCの出力がやけに長いなと思ったらこれループアンローリングされているのか。あわせて読みたいmelancholic afternoon。ざっくり要約すると、たとえばランダムな配列の最大値を求めるようなユースケースでは分岐予測が当たりやすいからjmpが2クロックぐらいで、5クロックのcmovより速くてもおかしくない、という感じの話。このコードやyuyarinのコードは比較の結果が予測不能だという仮定に立っているが、そもそもその仮定は本当に正しいのか。入力のパターンと切り離して最速のmaxを考えることは無意味ではないか?

ソースコード: https://gist.github.com/716660

A: return a > b ? a : b;

[sample] ave: 367.150000 msec, sd: 8.060789 msec, samples: 20
without first 5 samples: ave: 366.666667 msec, sd: 8.077010 msec

https://gist.github.com/716654

B: int c=a>b; return c*a+!c*b;

[sample] ave: 208.550000 msec, sd: 7.344708 msec, samples: 20
without first 5 samples: ave: 208.333333 msec, sd: 7.384024 msec

https://gist.github.com/716653

C: return (-(a>b))&a|(~(-(a>b)))&b;

[sample] ave: 187.500000 msec, sd: 7.126673 msec, samples: 20
without first 5 samples: ave: 187.533333 msec, sd: 5.878127 msec

https://gist.github.com/716652