メニエスの名のもとに

プログラミング関係を中心としたぐだぐだブログ

-O2 と -O3 は大違い

Oだけに。
いやあ、これまでg++ でコンパイルする時に -O3 を付けてたんだけど、-O2 とはそんなに違わないと思ってたんですよ。で、GitHubにソースを置くようになってからautotoolsを使うようになって、Makefile.am でやはり -O3 と指定して訳です。でも、ちょっとしたテストをするときのために、Makefile.private というのを作って、automakeの枠外で好き勝手にmakeしたりしていたのですが、今回いろいろやっていたら実行速度が大幅に違うのである。なぜ実行速度が違うのかわけが分からなくてしばらく悩んでいたのですが、autotools でmakeのメッセージをよく見ると、-O3 と指定したあとに、-O2 の指定が出てくるのである。ぐぐってみると、statckoverflow サイトに回答があった。
configure.acに

AC_INIT
...
: ${CFLAGS=""}
: ${CXXFLAGS=""}
AC_PROG_CXX
AC_PROG_CC
...

と書かなければならないらしい。
いや-O2と-O3で何が違うのかよくわからないが、どうもC++のテンプレートの最適化が違うようである。randomのuniform_int_distributionが大幅に違うのだ。そうそうg++のバージョンは5.4.0である。
uniform_int_distributionは優秀でした。
std::mt19937での10^8個の乱数生成

32bit int uniform int
318ms 381ms

sfmt19937をstd::randomのインターフェイスに合わせて10^8個の乱数生成

32bit int uniform int
114ms 168ms

ほんとにこんなに速いのか、計測を間違っているんじゃないかと思うくらい。

O2に戻してみると
std::mt19937での10^8個の乱数生成

32bit int uniform int
435ms 469ms

sfmt19937をstd::randomのインターフェイスに合わせて10^8個の乱数生成

32bit int uniform int
112ms 165ms

あれぇ、そんなに変わらないじゃないか。おかしいなぁ。