私は現在、C++で独自のMersenne Twisterの実装を行っています。Visual StudioコンパイラがMersenne-Twisterの実装でループをアンロールしないのはなぜですか?
void twistIteration(uint32_t i)
{
uint32_t x = (mt[i] & MASK_UPPER) + (mt[(i + 1) % N] & MASK_LOWER);
uint32_t xA = x >> 1;
if (x & 1)
{
xA ^= A;
}
mt[i] = mt[(i + M) % N]^xA;
}
注N、MとMASK_UPPERはテンプレート引数なので、それらはコンパイル時に知られていること:このアルゴリズムは、次の関数を複数回呼び出す必要。
void twist()
{
for (uint32_t i = 0; i < N; i++)
{
twistIteration(i);
}
index = 0;
}
このアルゴリズムで128.000.000の乱数を生成すると、私のマシンで約0.95秒かかってしまいます。しかし、私は非常に少しひねりの機能を変更することで、アルゴリズムを高速化する方法を見つけた:表現(i + 1) % N
と(i + M) % N
がで計算することができるように
void twist()
{
for (uint32_t i = 0; i < N - 1; i++)
{
twistIteration(i);
}
twistIteration(N - 1);
index = 0;
}
、私は、ループの最後の繰り返しをアンロールコンパイル時。同じ量の乱数は今や巨大な改善である0.60秒しかかかりません。 私の質問です:なぜコンパイラは私のためにこれをしないのですか?私はデフォルトのVS2017リリースモードでコンパイルし、「高速コード最適化だがより大きなコード」をtrueに設定しました。 Visual Studioコンパイラのいくつかの奇妙な振る舞いですか?
コンパイラがあなたのプログラムに最適なマシンコードを生成しない理由を尋ねているようです。 VC++ではこのような最適化を見ることができません。あなたのコードに対して_any_特定の最適化が実行されることは期待できません。 –
あなたが使用している 'cl'の正確なコマンドラインは何ですか? 'gcc'や' clang'のような別のツールチェーンを使用する場合は、最適化を行いますか? – Dai
私はコンパイラによって特定の最適化が行われるとは思っていませんが、特にコンパイル時にいくつかの式が分かっている場合は、基本的なループアンローリングが必要です。 – Brotcrunsher