メモリバリアの使用について理解できないことがあり、明確化を望んでいます。
したがって、Treibers スタックがあり、SMR を使用しているとします。したがって、各ポインターに関連付けられたカウンターはありません。アトミック操作でポインターを正しく取得する必要があります (これは ABA に関するものではありません。SMR を使用しています。それはABAを扱っていますが、それは問題の一部ではありません)。
ここで、Intel (x86/x64) で作業していると仮定して、すべての CAS に完全なメモリ バリアが付属しているとします。キャッシュラインがロックされ、読み取りバリアが発行され、無効化キューがクリアされ、キャッシュラインがロードされ、そのキャッシュラインの最新バージョンが読み込まれ、比較が行われ、書き込みバリアが発行されると、CASing が発生すると思います発行し、ストア バッファをフラッシュし、最後にキャッシュ ライン ロックを解放します。
したがって、次の pop のコードがあります。
BARRIER_PROCESSOR_READ;
original_top = stack_state->top;
do
{
if( original_top == NULL )
return( 0 );
copy_of_original_top = original_top;
original_top = compare_and_swap( &stack_state->top, original_top->next, original_top );
}
while( copy_of_original_top != original_top );
*user_data = original_top->user_data;
したがって、最初に読み取りバリアを発行します。これにより、無効化キューを確実にフラッシュします。しかし、そうすることと、state_state->top を読み取ることの間にギャップがあります。無効化キューをクリアしてから state_stack->top を読み取るまでの間に、何かが起こる可能性があります。コアは割り込みを処理し、バスの競合が発生し、非常に遅くなる可能性があります。名前を付けると、無効化されたキャッシュラインが再ロードされる可能性があります (別のプロセッサによって再度無効化される可能性があります)。基本的に - 無効化キューは補充できます。つまり、original_top の値を実際に信頼することはできません。実際には間違っているローカル キャッシュ ラインを読み取っている可能性があり (まだ無効化していません)、そうすることで、その値が NULL であると誤って認識し、0 を返します。
したがって、基本的に、読み取りバリアがどのように役立つかはわかりません。バリアの後でも、実行したい実際の読み取りの前に何かが起こる可能性があるためです。
ここで何が欠けていますか?