トップページ > プログラム > 2015年10月31日 > xh8OJ8ET

書き込み順位&時間帯一覧

1 位/196 ID中時間01234567891011121314151617181920212223Total
書き込み数0031000000000000002001108



使用した名前一覧書き込んだスレッド一覧
デフォルトの名無しさん
C++相談室 part120 [転載禁止]©2ch.net

書き込みレス一覧

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


※このページは、『2ちゃんねる』の書き込みを基に自動生成したものです。オリジナルはリンク先の2ちゃんねるの書き込みです。
※このサイトでオリジナルの書き込みについては対応できません。
※何か問題のある場合はメールをしてください。対応します。