15

参照カウントを使用して管理し、SMP システム上のスレッド間でそれらを共有したい不変のデータ構造がいくつかあります。

リリースコードは次のようになります。

void avocado_release(struct avocado *p)
{
    if (atomic_dec(p->refcount) == 0) {
        free(p->pit);
        free(p->juicy_innards);
        free(p);
    }
}

atomic_decその中にメモリバリアが必要ですか?もしそうなら、どのようなメモリバリアですか?

追加メモ: アプリケーションは PowerPC と x86 で実行する必要があるため、プロセッサ固有の情報を歓迎します。GCC アトミックビルトインについてはすでに知っています。不変性に関しては、refcount はオブジェクトの存続期間中に変化する唯一のフィールドです。

4

3 に答える 3

16

lockx86 では、 のようなプレフィックス付きのアセンブリ命令に変わりLOCK XADDます。
単一の命令であるため、割り込み不可です。追加された「機能」として、lockプレフィックスは完全なメモリ バリアをもたらします。

「...ロックされた操作は、すべての未処理のロードおよびストア操作をシリアル化します (つまり、それらが完了するのを待ちます)。」...「ロックされた操作は、他のすべてのメモリ操作および外部から見えるすべてのイベントに関してアトミックです。ロックされた命令を渡すことができるのは、命令フェッチとページ テーブル アクセスのみです。ロックされた命令は、あるプロセッサによって書き込まれたデータと別のプロセッサによって読み取られたデータを同期するために使用できます。 ." - Intel® 64 and IA-32 Architectures Software Developer's Manualの第 8.1.2 章。

メモリ バリアは、実際にはダミーとして、LOCK ORまたはx86/x64の .NETJava JIT のLOCK AND両方で実装されています。これは、64 ビット モードのように、利用可能であることが保証されている場合でも、多くの CPU で速度が低下するためです。( lock xchg は mfence と同じ動作をしますか? ) したがって、好むと好まざるとにかかわらず、追加ボーナスとして x86 に完全なフェンスがあります。:-)mfence

PPC の場合は異なります。内部に減算を含むLL/SCペア - lwarx&stwcx - を使用して、メモリ オペランドをレジスタにロードし、1 を減算してから、ターゲット位置へのストアが他にない場合はそれを書き戻すか、存在する場合はループ全体を再試行します。だった。LL/SC は中断される可能性があります (つまり、失敗して再試行されます)。
また、自動フルフェンスという意味でもありません。
ただし、これによってカウンターの原子性が損なわれることはありません。
これは、x86 の場合、たまたま「無料」でフェンスも取得できることを意味します。
PPC では、命令を発行することで (部分的または) 完全なフェンスを挿入できます。(lw)sync

全体として、アトミック カウンターが適切に機能するために、明示的なメモリ バリアは必要ありません。

于 2010-04-08T20:55:51.857 に答える
9

アトミック アクセス (値の読み取り/変更/書き込みが 1 つのアトミック ユニットとして実行されることを保証する) とメモリの並べ替えを区別することが重要です。

メモリ バリアは、読み取りと書き込みの並べ替えを防ぎます。並べ替えは原子性と完全に直交しています。たとえば、PowerPC では、可能な限り最も効率的なアトミック インクリメントを実装すると、並べ替えが妨げられません。並べ替えを防ぎたい場合は、lwsyncまたはsync命令、または同等の高レベル (C++ 11?) メモリ バリアが必要です。

コンパイラの最適化は非常に驚くべきものであり、CPU (特に PowerPC/ARM/Alpha/MIPS) はメモリ操作を積極的に並べ替えるため、「コンパイラが問題のある方法で並べ替えを行う可能性はない」という主張は、一般的なステートメントとしては素朴に思えます。

コヒーレントなキャッシュもあなたを救いません。メモリの並べ替えが実際にどのように機能するかについては、 https://preshing.com/archives/を参照してください。

ただし、この場合、答えは障壁は必要ないということだと思います。これは、この特定のケース (参照カウント) では、参照カウントとオブジェクト内の他の値との間の関係が必要ないためです。1 つの例外は、参照カウントが 0 になったときです。その時点で、他のスレッドからのすべての更新が現在のスレッドに見えるようにすることが重要であるため、読み取りと取得のバリア必要になる場合があります。

于 2015-02-17T22:13:29.640 に答える
2

独自の関数を実装するつもりですatomic_decか、それともシステム提供の関数が希望どおりに動作するかどうか疑問に思っているだけですか?

原則として、システムが提供するアトミック インクリメント/デクリメント機能は、正しいことを行うために必要なメモリ バリアを適用します。独自のロックフリー データ構造や STM ライブラリを実装するなどの奇抜なことをしない限り、通常はメモリ バリアについて心配する必要はありません。

于 2010-04-08T11:02:05.910 に答える