2

一般的な質問ですが、

マルチスレッド プログラムでは、コンパイラがレジスタを使用してグローバル変数を一時的に格納しても安全ですか?

グローバル変数をレジスタに格納すると、他のスレッドの保存された値が変更される可能性があるため、そうではないと思います。

また、関数内で定義されたローカル変数を格納するためにレジスタを使用するのはどうですか?

他のスレッドはこれらの変数を取得できないため、問題ないと思います。

間違っている場合は修正してください。ありがとうございました!

4

3 に答える 3

4

物事はあなたが思っているよりもはるかに複雑です。

コンパイラが値をメモリに格納している場合でも、CPUは通常データをRAMにすぐにプッシュしません。キャッシュに保存します(一部のシステムでは、プロセッサとメモリの間に2つまたは3つのレベルのキャッシュがあります)。

さらに悪いことに、多くのプロセッサが独自のパイプラインで命令(および命令のサブパート)を並べ替えることができるため、コンパイラが決定する命令の順序は実際に実行される順序ではない場合があります。

一般に、マルチスレッド環境では、次のいずれかに該当しない限り、2つの別々のスレッドから同じメモリにアクセス(読み取りまたは書き込み)しないように個人的に注意する必要があります。

  • 適切な同期を保証するいくつかの特別なアトミック操作の1つを使用しています。
  • いくつかの同期操作の1つを使用して、共有データへのアクセスを「予約」してから、それを「放棄」しました。これらには、データが想定どおりであることを保証するために必要なメモリバリアが含まれています。

http://en.wikipedia.org/wiki/Memory_ordering#Memory_barrier_typesおよびhttp://en.wikipedia.org/wiki/Memory_barrierを読むことをお勧めします

少し頭痛の種になる準備ができていて、実際にどれほど複雑なことが起こり得るかを知りたい場合は、ここに夕方の講義「メモリバリア:ソフトウェアハッカーのためのハードウェアビュー」があります。

于 2012-08-10T15:12:05.730 に答える
1

「安全」という言葉は適切ではありません。多くの高水準言語 (C など) にはスレッド モデルがないため、言語仕様にはマルチスレッドの相互作用については何も記載されていません。

いかなる種類のロック プリミティブも使用していない場合は、異なるスレッドがどのように相互作用するかについて何の保証もありません。したがって、コンパイラは、グローバル変数にレジスタを使用する権利を持っています。

ロックを使用している場合でも、動作は依然としてトリッキーになる可能性があります。変数を読み取り、ロックを取得してから変数を再度読み取る場合、コンパイラはメモリから変数を再度読み取る必要があるかどうかを知る方法がありません。レジスタに格納された以前の値を使用します。

C/C++ で変数を volatile として宣言すると、コンパイラは常にメモリから変数を再読み込みし、この特定のインスタンスを解決するように強制されます。

ほとんどのシステムには、特定の操作がスレッドセーフであることを保証するために使用できる原子性セマンティクスが保証された「Interlocked*」プリミティブもあります。ロック プリミティブは通常、これらの低レベル操作に基づいて構築されます。

于 2012-08-10T15:10:25.820 に答える
0

マルチスレッド プログラムでは、次の 2 つのケースのいずれかになります。ユニプロセッサ (シングル コア、シングル CPU) で実行されている場合、スレッド間の切り替えは、プロセス間の切り替えのように処理されます (ただし、スレッドはプロセス内で動作するため、それほど多くの作業は必要ありません)。同じ仮想メモリ空​​間) - あるスレッドのすべてのレジスタは、別のスレッドへの移行中に保存されるため、目的に関係なくレジスタを使用しても問題ありません。これは、OS が使用するコンテキスト切り替えルーチンの仕事であり、レジスタ セットはスレッド (またはプロセス) コンテキストの一部と見なされます。マルチプロセッサ システム (複数の CPU または 1 つの CPU 上の複数のコア) を使用している場合、各プロセッサには独自のレジスタ セットがあるため、レジスタを使用して物事を格納することは問題ありません。その上、もちろん、

とはいえ、一部のアーキテクチャや一部の OS では、特定の例外が存在する可能性があります。これは、特定のレジスタが、OS または OS へのインターフェイスを提供するライブラリによる特定の使用のために ABI によって予約されているためです。 (s)一般に、プラットフォームに関するそのような知識が組み込まれています。ただし、インラインアセンブリやその他の「低レベル」のことを行っている場合は、それらに注意する必要があります...

于 2012-08-10T15:08:28.673 に答える