intel のプロセッサ マニュアル:セクション 8.2.3.4 のリンクでは、ロードは以前のストアを別の場所に並べ替えることができるが、以前のストアを同じ場所に並べ替えることができないと記載されています。
したがって、次の 2 つの操作を並べ替えることができることを理解しています。
x = 1;
y = z;
また、次の 2 つの操作は順序を変更できません。
x = 1;
y = x;
しかし、ストアとロードが別の場所にある場合、ロードはストアを完全に取り囲んでいます。たとえば、次のようになります。
typedef union {
uint64_t shared_var;
uint32_t individual_var[2];
} my_union_t;
my_union_t var;
var.shared_var = 0;
var.individual_var[1] = 1;
int y = var.shared_var;
では、この場合の 'y' は 0 にできますか?
編集(@Hans Passant) 状況をさらに説明するために、この手法を使用して、ロックされた命令を使用せずにスレッド間の一種の準同期を考案できるかどうかを確認しようとしています。
したがって、グローバル変数が与えられた場合のより具体的な質問は次のとおりです。
my_union_t var;
var.shared_var = 0;
そして、次のコードを実行する 2 つのスレッド:
スレッド 1:
var.individual_var[0] = 1;
int y = __builtin_popcountl(var.shared_var);
スレッド 2:
var.individual_var[1] = 1;
int y = __builtin_popcountl(var.shared_var);
両方のスレッドで 'y' を 1 にすることはできますか?
注: __builtin_popcountl は、変数に設定されたビット数をカウントする組み込みの gcc 組み込み関数です。