3

私はC++で書かれたネイティブマルチスレッドWin32アプリケーションを持っています。これには、約3つの比較的ビジーなスレッドと4〜6のスレッドがあります。通常モードで実行すると、8コアマシンで合計CPU使用率が約15%になり、アプリケーションは約30秒で終了します。また、アフィニティマスクを設定して、アプリケーションを1つのコアのみに制限すると0x01、23秒で完了します。

1つの物理コアに制限されている場合や、同時メモリアクセスの問題がある場合に、同期が安価になることと関係があると思います。

私はWindows7x64を実行していますが、アプリケーションは32ビットです。CPUはXeonX5570で、4コアとHTが有効になっています。

誰かがその振る舞いを詳細に説明できますか?なぜそれが起こるのか、そしてそのような行動を前もって予測する方法は?

更新:私の質問はあまり明確ではなかったと思います。複数のコアで15%を超えない理由ではなく、1つの物理コアで高速になる理由を知りたいです。

4

5 に答える 5

7

質問は非常にあいまいなので、典型的なスレッドの問題に基づいてランダムに推測します。

明らかな候補は競合です。スレッドはロックをめぐって争い、事実上、並列ではなく直列で実行されます。スレッドコンテキストスイッチの料金を支払うことになり、メリットはありません。これはC++では見逃しがちな問題であり、CRTおよびC++標準ライブラリでは多くの低レベルのロックが行われています。どちらも元々、スレッド化を考慮せずに設計されました。

x86やx64などの強力なメモリモデルを備えたCPUコアで一般的な問題は、「偽共有」です。これは、複数のスレッドが同じL1キャッシュライン内のメモリ位置を更新するときに発生します。次に、プロセッサはコアキャッシュの同期を維持するために多くの馬力を消費します。

プログラムが実際に実行にバインドされている場合にのみ、複数の実行コアからメリットを得ることができます。そのメモリがバインドされている場合、あなたは利益を得ることができません。操作するデータがCPUキャッシュに収まらない場合、マシンにはまだ1つのメモリバスしかなく、その強力なボトルネックがあります。バスが追いつくのを待って、コアは単にストールします。それでもCPU時間としてカウントされるため、CPU使用率の統計には表示されませんが、実際の作業はほとんど行われていません。

明らかに、この種の問題を追跡するには、優れたプロファイラーが必要です。

于 2012-09-11T12:25:49.060 に答える
2

アプリケーションを特定しないと、アプリケーションの実行が遅い原因を推測することは困難です。詳細な分析が必要な場合は、次の要因を考慮することができます -

  • InterProcessor Communication : アプリケーション内のスレッドが相互に通信する量。彼らが非常に頻繁に通信する場合、この動作によりオーバーヘッドが発生します

  • プロセッサ キャッシュ アーキテクチャ: これは、確認すべきもう 1 つの重要な要素です。スレッドが異なるプロセッサで実行されているために、プロセッサのキャッシュがどのように影響を受けるかを知っておく必要があります。共有キャッシュで発生するスラッシングの量。

  • ページ フォールト: 単一のプロセッサで実行すると、プログラムのシーケンシャルな性質により、ページ フォールトの数が減る可能性があります。

  • Locks : コードのオーバーヘッドをロックしますか? これにより速度が低下することはありません。ただし、上記の要因に加えて、これによりオーバーヘッドが発生する可能性があります。

  • プロセッサの NoC : 間違いなく、異なるプロセッサ コアに異なるスレッドを割り当て、それらが通信している場合、それらがどのようなパスをたどっているかを知る必要があります。それらの間に専用の接続はありますか?おそらく、このリンクを見てください。

  • Processor Load : 最後になりましたが、他のプロセッサコアで他のタスクを実行していないことを願っています。これにより、多くのコンテキストスイッチが発生しています。通常、コンテキスト スイッチは非常にコストがかかります。

  • 温度: 考慮すべき影響の 1 つは、CPU コアが過熱している場合にプロセッサ クロックが遅くなることです。この影響はないと思いますが、周囲温度にも大きく依存します。

于 2012-09-17T14:14:14.493 に答える
2

メモリのレイテンシがパフォーマンスに与える影響が大きいことを考えると、これはほぼ確実にキャッシングに関係しています。

単一のコア上にあることで、第 1 レベルと第 2 レベルのキャッシュが特にホットに保たれます。複数のコアに分散している場合よりもはるかにホットです。

第 3 レベルのキャッシュはすべてのコア間で共有されるため、違いはありませんが、もちろん速度は大幅に低下するため、ローカリティを第 1 レベルと第 2 レベルのキャッシュに移動することで多くのメリットが得られます。

于 2012-09-17T14:21:25.073 に答える
2

「通常モードで実行すると、合計 CPU 使用率は 8 コア マシンで約 15% になります」

わずか 15% の使用率は、別の考えられる理由を示唆しています。あなたのスレッドは I/O を行っていないのでしょうか? 私の推測では、CPU 使用率ではなく、I/O 操作がアプリケーションの全体的な時間を決定します。また、ほとんどの場合、I/O ジョブがマルチスレッド化されていると、I/O 集中型アプリの速度が低下します (2 つのファイルを同時にコピーする場合と、次々にコピーする場合を考えてみてください)。

于 2012-09-17T15:12:34.060 に答える
1

問題に関する限り、スレッドは複数のコアで実行されている間に相互に通信するため、プロセスの実行速度が比較的遅くなります。スレッドを単一の物理コアに制限すると、スレッド間の相互通信が不要になるため、プロセスが高速化されます。

これは、実行されるタスクにも依存する可能性があります。スレッドが必要とするリソースが少ない場合は、これが当てはまる可能性があります。それ以外の場合、物理コアを 1 つのコアに制限しても、すべての場合に効果的であるとは限りません。

于 2012-09-17T08:22:43.693 に答える