3

JavaプロセスとC++プロセスが共有メモリセグメントを介して相互に通信しています(Java側の通信にjniを使用)。Javaに1つのスレッドがあり、C ++に1つのスレッドがある場合、コードはまともな速度で実行されますが、プロセスで複数のスレッドを使用するとすぐに、パフォーマンスが大幅に低下します(ほぼ100倍)。

この後、コード(core2duoシステムで実行している)でいくつかの調整を行ったところ、1つのコアにjavaプロセスをマッピングすると(sched_affinity()を使用)、core1にcppプロセスをマッピングしたときにパフォーマンスが向上することがわかりました。回復します。

なぜこうなった?問題は共有メモリセグメントでのキャッシュの競合である可能性があると思いましたが、このコアマッピングによりパフォーマンスが向上します。また、この動作は、複数のスレッドが使用されている場合にのみ観察されます。両方のプロセスでシングルスレッドを使用する場合、速度は通常です。

4

1 に答える 1

3

2 つのスレッドがフル チルトで実行されている場合の "最適な" 構成は、それぞれにコアを持つことです。それらが動かされない場合、つまり各スレッドが「その」コアにとどまる場合、コア間を行き来する場合よりもパフォーマンスが向上します。したがって、基本的に 2+2 スレッド ソリューションを最適に実行するには 4 つのコアが必要です。

さらに、2 つのコアが同じコードを実行しているため、それら (あなたの場合) が「その」コアから移動されていないことが重要です。これは、両方のコアの動作環境が多かれ少なかれ同じであるため、すべてを別のコアにロードする必要がある場合よりも (キャッシュ レベルで) 切り替えが面倒ではないためです。

次に、メモリ システムの飽和の問題があります。「通常の」シングルスレッド プログラムは、通常、使用可能なメモリ帯域幅のすべてではないにしても、ほとんどを使い果たします。その速度は通常、メモリ システムがデータを提供する速度によって決まります。メモリ アクティビティが発生しない除算命令にいるときや、データの読み取りまたは書き込みを必要としないタイトなループにいるときなどの例外があります。他のほとんどの場合、メモリシステムはメモリをプログラムに押し込むために全力を尽くしており、多くの場合、プログラムがメモリを利用できるほど速くはありません.

これを考慮に入れていないプログラムは、メモリアクセスが必要なときに両方のスレッドが衝突し始め、これにより処理が大幅に遅くなるため、シングルスレッドよりもマルチスレッドの方が遅くなります。これは、C や C++ などのコンパイル済み言語用です。Java では、舞台裏で (エンジンが原因で) プログラマがほとんど制御できない多くのメモリ アクセスが行われています。そのため、Java エンジンとその動作は大量のキャッシュ メモリと帯域幅を使い果たします。これは、共有メモリがエンジンのニーズと競合し、多かれ少なかれ常にキャッシュに出入りすることを意味します。

私の2セント。

于 2012-06-06T09:34:58.567 に答える