2016-08-08 6 views
1

これは非常に基本的な場合は申し訳ありません。これは私がやっていることの単純化されたバージョンです。私はカーネルモジュールを書いています。実行中は2つの異なる物理CPUの2つのスレッドがあります。これらのスレッド間の通信を行うためにグローバル変数を使用しています。奇妙なことは、あるスレッドの書き込みがもう一方のスレッドだけで見られないことがあることです。理由は何でしょうか?1つのCPUによって書き込まれた値が他のCPUに見られないのはなぜですか?

私はそれがメモリ障壁とおそらくキャッシュ同期と関係があると思うので、書き込み後にsmp_wmb()を使用しようとしましたが、それは役に立たないようです。そして、私が知る限り、キャッシュ同期を明示的に制御することはできません。だから私はちょっと固まっている。

アイデア?

編集:説明が簡略化されたバージョンであることを明確にしてください。

+0

多くのことがあります。カーネルモジュールは私にCを仮定させるので、変数volatileを宣言しましたか? –

+0

@GabeSechanはい、私はそれを試みました。 – TFC

+0

他のカーネルコードが使用するパターンに従います。また、あなたが何か信じられないほど珍しいことをやっていない限り、書き込みメモリバリアは書き込みの前にあるべきです。この価値はどんな意味を持っていますか? –

答えて

-1

コンパイラの最適化のために問題に直面していると思います。

volatileを試しましたか?私はvolatileあなたのケースで動作すると思います。

volatileキーワードは、複数のソース(プロセス)からの変数に対して同時非同期操作が実行される場合に使用してください。変数がvolatileと宣言されている場合は、マイクロプロセッサのキャッシュに変数をコピーし、そこから変数にアクセスするのではなく、すべてのプロセスが常にそのメモリ位置から変数に直接アクセスします。

+0

volatile修飾子は一般に、変数の値がキャッシュにあるのかメモリにあるのかに影響しません。通常、変数の値が一時的にレジスタに保持されるかどうかにのみ影響します。 –

0

まず、間違っています。 CPU間の適切な同期は非常に複雑で、アーキテクチャ固有の問題です。スレッド同期には、既存のカーネルメカニズムを使用する必要があります。特定のパフォーマンスが必要な場合を除き、スピンロックを使用してください。次に、必要に応じて、さまざまな同期メカニズムについて少しお読みいただき、ワークロードに最も適したものを見つけてください。

質問に直接答えるには、ここで直面している可能性がある少なくとも2つの問題があります。 1.コンパイラによる命令の並べ替えは、通常コンパイラの壁(つまりbarrier())で処理されます。 2.通常、メモリ障壁によって処理されるCPUおよびキャッシュのコヒーレンシによるアウト・オブ・オーダーの実行。

詳細は、アーキテクチャと用途に固有ですが、分析できるコードやアーキテクチャの詳細は提供していません。したがって、少なくともbarrier()smp_wmb()smp_rmb()、およびsmp_read_barrier_depends()のいずれかとすべてを使用する必要があります。

関連する問題