17/07/09 20:58:18.04 P60p5X3m0.net
>>392
専門的な話題で申し訳ない。volatile longはlongと少し違うが、同期実行のためには全然足りない。
void test1(long *p) {
++*p; ++*p;
} は
test1:
increment *p <- pの中にp+1を入れる(内部的にはp読み出し、1加算、p書き込み)
increment *p <- 2個目
return
とコンパイルされるが(擬似コード)、二度書き込むのもったいないから
test1:
move %temp, *p <- pの中身をtempレジスタに入れる
add 2, %temp <- tempレジスタに2を足す
move %temp, *p <- tempレジスタの内容をpに入れる
return
と1回の書き込みに最適化される(可能性がある)。それを明示的に書かれた回数通りにするのがvolatile修飾
void test2(volatile long *p) {
++*p; ++*p;
} はpに対するそれぞれの操作が必ず1度書き込まれることが保証されるので1つ目の擬似コードが出力される。
C++で導入されたstd::atomic_intは、複数のコアで同時実行されても結果が保証されるようになる。
void test3(std::atomic_int *p) {
++*p; ++*p;
} は
test3:
lock increment *p <- lockがすべてのCPUで調停する命令(プレフィックス)
lock increment *p
return
ここで、lock prefixがついていないincrement *pが同時実行されると
Core0 Core1
load *p
load *p
++temp
store temp
++temp
store temp
と実行順序が一貫性を失うことが起こりうる。これがvolatileで足りないケース
本当ははこの人は、実行されるコードを動的に変更して一貫性があるかどうかの差を見せたかったんだろうけど
何が起きたかって「私は並列プログラミングできません」と書かれたコードを世界中に晒したっていう