知られているように、std::atomic
とvolatile
は異なるものです。標準C++ 11は `volatile atomic <T>`に両方のセマンティクス(volatile + atomic)があることを保証していますか?
2つの主な相違点があります。
二つの最適化が
std::atomic<int> a;
のためにすることができますが、volatile int a;
のためにすることはできません。- 融合操作:
a = 1; a = 2;
はa = 2;
にコンパイラによって置き換えることができますが、 - 定数伝播:
a = 1; local = a;
は、コンパイラで置き換えることができます。a = 1; local = 1;
ため
- 任意の揮発性の読み取り/書き込み操作を並べ替えることができません。普通の
の並べ替えは、/は、揮発性/アトミック操作間で読み書きを行います。しかし、近くの通常の読み取り/書き込みは、揮発性の読み取り/書き込みの前後で並べ替えることができます。
- 近く通常の
std::atomic a;
並べ替えのために/をアトミック操作a.load(std::memory_order_...);
- 融合操作:
即ちために使用されるメモリバリアに基づいて制限読み書きvolatile
メモリフェンスを導入していませんが、std::atomic
が可能です。
:
- ハーブサッター、2009年1月8日 - パート1:http://www.drdobbs.com/parallel/volatile-vs-volatile/212701484
- ハーブサッター、2009年1月8日 - パート2:http://www.drdobbs.com/parallel/volatile-vs-volatile/212701484?pgno=2
例えば、std::atomic
は、同時マルチスレッドプログラム(CPUコア< - > CPUコア)に使用する必要がありますが、デバイス上のMamory Mapped Regionへのアクセスにはvolatile
を使用してください(CPUコア< - >デバイス)。必要に応じて
しかし、両方のは異例の意味を持っており、および/またはロックフリー符号化のために必要な保証を注文する、すなわち、原子のいずれかまたは全てを持っていますvolatile std::atomic<>
を必要に応じて、いくつかの理由のために必要:
- はを注文:通常の並べ替えを防止するために、データがデバイスDMAコントローラを使用して書き込まれたCPU-RAMからの読み出しのために/は、例えば、読み書き例えば
:がこぼれる
char cpu_ram_data_written_by_device[1024];
device_dma_will_write_here(cpu_ram_data_written_by_device);
// physically mapped to device register
volatile bool *device_ready = get_pointer_device_ready_flag();
//... somewhere much later
while(!device_ready); // spin-lock (here should be memory fence!!!)
for(auto &i : cpu_ram_data_written_by_device) std::cout << i;
- :CPU-RAMへのCPU書き込みと、このメモリから読み出されたデバイスのDMAコントローラ:https://en.wikipedia.org/wiki/Register_allocation#Spilling
例:
char cpu_ram_data_will_read_by_device[1024];
device_dma_will_read_it(cpu_ram_data_written_by_device);
// physically mapped to device register
volatile bool *data_ready = get_pointer_data_ready_flag();
//... somewhere much later
for(auto &i : cpu_ram_data_will_read_by_device) i = 10;
data_ready=true; //spilling cpu_ram_data_will_read_by_device to RAM, should be memory fence
- 原子:揮発性動作がアトミックであることを保証しますつまり、複数の代わりに1回の操作、つまり2つの4バイト操作の代わりに1つの8バイト操作で構成されます。
このために、ハーブサッター約volatile atomic<T>
、2009年1月8日言った:http://www.drdobbs.com/parallel/volatile-vs-volatile/212701484?pgno=2最後に
、両方が異例の意味を持っており、 いずれかまたはアトミックの全ておよび/または のために必要な保証を注文を持つ変数を表現しますロックフリーのコーディングでは、ISO C++ 0xドラフトスタンダードのみが直接 という綴り方を提供しています。
しかし、やる現代標準C++ 11(ないC++ 0xのドラフト)、C++ 14、及びvolatile atomic<T>
は(揮発性+原子)の両方の意味を持っていることをC++ 17保証?
volatile atomic<T>
は、volatileとatomicの両方から最も厳しい保証をしていますか? volatile
のよう
- :
std::atomic
のように質問 - の冒頭に記載したように溶融操作および定数伝播を回避するには:こぼれ、順序を提供するために、メモリフェンスを導入し、アトミックです。
reinterpret_cast
volatile int *ptr;
からvolatile std::atomic<int>*
までは可能ですか?
私は短いコメントを投げさせてください。 'volatile atomic'を 'atomic 'に置き換え、なぜ 'reinterpret_cast'をやりたいのですか?おそらく動作しますが、保証されません。 –
DeiDei
揮発性の型は簡単にコピーできないため、 'std :: atomic'は使用できません。 –
Brian
@Brianはい、あなたは正しいです。 'std :: atomic'について削除されました。 –
Alex