Volatile: Almost Useless for Multi-Threaded Programming | Intel® Software
https://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming
マルチスレッドプログラミングではvolatileキーワードを使うものと思われてる。しかし、volatileは何の効果もないばかりか、実行速度が遅くなるというデメリットしかもたらさない場合がある。volatileの勘違いは主に次の2点。
1. アトミック性
volatileはアトミックなreadやwriteを保証しない。129バイトの構造体はvolatileをつけてもアトミックにならないし、32bit整数はvolatileをつけなくてもアトミックになる。
2. メモリ一貫性(consistency)
volatileをメモリアクセスの最適化を無効にするものだと思うのは間違いである。
例えば
messageへの書き込みとreadyへの書き込みの順番は最適化で入れ替わることがある。メモリfenceが必要だがvolatileはメモリfenceに関係しない。
volatile int ready;
int message[100];void foo(int i){
message[i/10] = 42;
ready = 1;
}
- -
この記事は間違っている。
コンパイラは最適化でループを何もしない無限ループに置き換えてもよい。
int done = false;
int fool() {
while(!done) {
somecounter ++;
}
}
コンパイラがdone変数がvolatileだと知るためには、volatile修飾子を使わなければならない。
- -
この記事は単純に間違っている。
volatileは、関数内で変数を変更してないので定数だとコンパイラが勘違いするような状況で、常に必要となる。mutexやメモリfenceを入れても、コンパイラの勘違いは解決しない。