3

マルチプロセッサシステムの共有メモリxに変数があります。

void MyFunction(volatile int* x) {
  if (*x != 0) {
     // do something
  }
}

他のプロセス(おそらく異なるプロセッサ上)は、__sync_bool_compare_and_swapなどのgcc組み込みアトミック操作を使用してxに書き込みます。

xが最終的に新しい値で更新されるまでに少し時間がかかることがある、キャッシュの同時実行性の問題が発生していると思います。

そのようなものが存在する場合、私が欲しいのは一種のatomic_compare(スワップなし)ですか?または「アトミックリード」。これを行うための最速の方法は何ですか?(ミューテックス、ロックなどを回避します)

ありがとう

編集:

ややハックな回避策は、__sync_val_compare_and_swapを、決して使用できないことがわかっている値で使用することであることに気づきました。それで問題は解決しますか?(よりクリーンな方法はありますか?)

4

3 に答える 3

4

新しいC標準であるC11には、_Atomicこれに対処するためのデータ型と操作があります。この標準はまだ実装されていませんが、gccとclangはそれに近く、すでに機能を実装しています。そして実際、関数 __sync_bool_compare_and_swapはその一部です。私はそれをP99のヘッダーのセットにラップしました。これにより、C11インターフェースですでにプログラムすることができます。

C11関数は、atomic_load必要に応じて、またはコヒーレンスに特定の要件がある場合に実行しますatomic_load_explicit。そして当然のことながら、ご想像のとおり、P99はそれをにマッピングし__sync_val_compare_and_swap(&x, 0, 0)ます。x次に、これがほとんどのアーキテクチャで生成するアセンブラを調べると、これは、ビーイングの場合の単純なロード操作に変換されintます。しかし、これは言語によって保証されていません。そのようなことを知り、アトミックであることが保証されている命令を合成するのはコンパイラー次第です。

于 2012-06-30T06:15:18.593 に答える
2

これを行うための最速の方法は何ですか?(ミューテックス、ロックなどを回避します)

ミューテックスを避けたくないと確信しています。Linuxのfutexを使用すると、従来のミューテックスセマンティックを維持しながら(ほとんどの場合)コンペアアンドスワップの長所を活用できます(発生する「スワップ」はミューテックスの1つであり、それによって保護されるコード/データではありません)。perfそれらを試してソリューション( 、、oprofileVTuneなど)のプロファイルを作成し、ボトルネックがキャッシュ使用率、メモリスループット、CPUサイクル、IOアクセス、リモートノードなどではなく、ロックメカニズム自体に実際に関連しているかどうかを確認することを強くお勧めします。メモリアクセスなど。

xが最終的に新しい値で更新されるまでに少し時間がかかることがある、キャッシュの同時実行性の問題が発生していると思います。

さて、あなたが本当にプロセッサ間で相互作用する必要があり、futexから得られるレイテンシーヒットを測定し、それがアプリケーションのニーズを満たさないと判断したと仮定しましょう。したがって、その場合は、比較的適切な方法で次のように進めることができます。ターゲットのキャッシュラインのサイズ以上の距離でパディングされた32ビット整数の配列を作成します。現在実行中のCPUとキャッシュラインのサイズを、このリストの実際の値へのインデックスとして使用します(したがって、キャッシュラインが64バイトの場合、CPU#を16でスケーリングして、パディングを飛び越えます)。これらの値は適切なCPUからのみ書き込む必要があり、他のCPUからポーリングできます(おそらく、ビジーウェイトの本体でCPUの「一時停止」命令の1つを呼び出す必要があります)。

これはほぼ確実に機能しますが(CPU効率を、おそらくより低いレイテンシーと効果的に交換します)、非常に特定のハードウェアセットを除くすべてのソリューションに対して非常に脆弱なソリューションであり続けることを付け加えておきます。

于 2012-06-30T01:51:08.983 に答える
0

そのようなものが存在する場合、私が欲しいのは一種のatomic_compare(スワップなし)ですか?または「アトミックリード」。

比較はすでにアトミックです。これは1回の読み取りです。

プロセッサ間のレイテンシがすでにそれほどひどい場合は、コードを少し切り離すことでコードにメリットがあるようです。つまり、依存関係を少し分離して、内部ループでこの種の通信に依存しないようにします。

于 2012-06-30T02:02:47.870 に答える