- C++相談室 part120 [転載禁止]©2ch.net
252 :デフォルトの名無しさん[sage]:2015/10/31(土) 02:17:43.79 ID:xh8OJ8ET - コンパイラの使命はソースコードに書かれたアルゴリズムと等価なオブジェクトコードを生成すること
つまりアルゴリズムの等価性が証明できる範囲内なら何だってする 外部リンケージの関数呼び出し順序を入れ替えないのは、 外部リンケージの関数が副作用を持たないことの証明が高コスト過ぎて割に合わないからやらないだけにすぎない 外部リンケージの関数呼び出し順序は未来永劫変わることはないのだと安心しきっていると ある日マルチスレッド状況下で反乱されて人類は死ぬ volatileの手綱は決して緩めてはならぬ
|
- C++相談室 part120 [転載禁止]©2ch.net
255 :デフォルトの名無しさん[sage]:2015/10/31(土) 02:43:19.73 ID:xh8OJ8ET - >>253
int a = foo(x); int b = bar(y); int c = baz(a); という呼び出しはbar()とbaz()の呼び出し順序が変わり得るが (今のコンパイラがやらないのは>>252に書いたとおりだが、bar()とbaz()の間に順序依存の副作用が無いなら入れ替えてもアルゴリズムの等価性を変えない)、 int a = foo(x); volatile int b = bar(y); volatile int c = baz(a); ならbへの代入とcへの代入の入れ替えは許されないからbar()とbaz()の呼び出しの入れ替わりも無くなる >>254 volatileの仕様を正しく考えたことが無い人
|
- C++相談室 part120 [転載禁止]©2ch.net
256 :デフォルトの名無しさん[sage]:2015/10/31(土) 02:52:53.21 ID:xh8OJ8ET - つなみにコンパイラはアルゴリズムと言う言葉を決定論的な意味にしか捉えないから
コンパイラが思い描くアルゴリズムの等価性は マルチスレッド状況下でしばしば崩れてしまう プログラマを巻き添になる マルチコア状況でOoOが絡むとさらに最悪で、volatileでも力不足でメモリバリアを明示的にする必要がしばしばある VCなら2005以降のバージョンはマイクロソフトが良心的に対応してくれているから気づいていない人も多いが 人類は気を抜くとコンパイラの最適化に滅ぼされる…!
|
- C++相談室 part120 [転載禁止]©2ch.net
258 :デフォルトの名無しさん[sage]:2015/10/31(土) 03:04:19.63 ID:xh8OJ8ET - >>257
>別にメモリバリアが作られるわけじゃないですよ いやそれが! ttp://yamasa.hatenablog.jp/entry/20090720/1248089123
|
- C++相談室 part120 [転載禁止]©2ch.net
291 :デフォルトの名無しさん[sage]:2015/10/31(土) 18:38:49.04 ID:xh8OJ8ET - >>287
>C++の仕様で順番が決まってなくて、環境によって結果すら変わってしまう話 int a = 1; printf("%d, %d, %d, %d\n", ++a, ++a, ++a, ++a); とか int x = (++a) * (--a); みたいなやつぐらいしか思いつかん…
|
- C++相談室 part120 [転載禁止]©2ch.net
292 :デフォルトの名無しさん[sage]:2015/10/31(土) 18:42:00.24 ID:xh8OJ8ET - ていうか、
>最適化は結果が変わらない範囲で行われるのが普通だから、 >>291式の言語仕様で順序不定とされている呼び出し順に起因する場合を除き、 シングルスレッド状況で最適化前後で結果が変わる最適化はバグ
|
- C++相談室 part120 [転載禁止]©2ch.net
295 :デフォルトの名無しさん[sage]:2015/10/31(土) 21:59:37.38 ID:xh8OJ8ET - 指摘される前に言うが>>255の2番目のコードでもbar()→baz()の呼び出し順が書いたとおりになることはちょう賢いコンパイラの前では保証されない
>>255で例示すべきコウドは次のやつだった; int g_a; // g_aは別スレッドから書き換えられるグローバル変数 void foo(int y) { for (;;) { foo(y); int x = g_a; if (x != 0) bar(x) else baz(x); } これは、foo()の中身を理解し切るほどには賢くないコンパイラなら安全のためfoo()の呼び出し位置を動かさないから動くが、 ちょう賢いコンパイラがfoo(y)をループ外に出しても問題ない程度の副作用しかないと見切った瞬間 int x=g_a;もループ外に出せるじゃん?!となって別スレッドからのg_aの書き換えに反応しなくなる g_aにはvolatileが無いとそうなる
|
- C++相談室 part120 [転載禁止]©2ch.net
296 :デフォルトの名無しさん[sage]:2015/10/31(土) 22:03:54.48 ID:xh8OJ8ET - スマンfor(;;)ループ内のfoo()はhoge()に読み替えてホスイ…orz
|