2

私は、何千もの小さなテキストファイルをメモリに読み込み、データをstlコンテナに格納することから始まる、より大きなC++プログラムを持っています。これには約1分かかります。定期的に、コンパイルは、プログラムの最初の部分が約22〜23%のCPU負荷で実行される動作を示します。そのステップが終了すると、CPUは約100%に戻ります。O2フラグがオンになっていると発生する可能性が高くなりますが、一貫性はありません。-pフラグを使用すると、プロファイリングがほとんど不可能になるため、発生頻度はさらに低くなります。一度キャプチャしましたが、gprofの出力は役に立ちませんでした。CPU使用率が低い場合でも、すべてが同じ相対速度で実行されます。

これは複数のコアとは何の関係もないと私は確信しています。私はクアッドコアCPUを持っており、ほとんどのコードはマルチスレッドですが、シングルスレッドを実行してこの問題をテストしました。また、問題のあるステップを複数のスレッドで実行すると、各スレッドは最大20%のCPUでしか実行されません。

質問が曖昧であることを前もってお詫びしますが、それをさらにトラブルシューティングする方法についてのアイデアが不足しているので、ヒントが役立つかもしれません。

更新:明確にするために、コードの問題のある部分(コンパイルの約30〜40%)が100%CPUで実行されることがあるため、I /Oがボトルネック

4

3 に答える 3

4

バッファキャッシュです


私の推測では、Linux バッファキャッシュが動作している結果が表示されていると思います。

これらの数千のファイルはディスクからの読み込みに長い時間がかかり、CPUは主にローテーションを待機してレイテンシーを求めます。報告されたCPU使用時間は、パーセンテージで表して低くなります。(しかし、おそらく全体的には大きいでしょう。)

ただし、一度読み取られると、これらの小さなファイルはメモリに完全にキャッシュされ、各ファイルへのアクセス(以降の実行)は純粋にCPUにバインドされたアクティビティになります。

ブロックがキャッシュに残るかどうかは、再コンパイルなどの介入アクティビティによって異なります。新しいプログラムが実行され、他のファイルが読み取られると、プログラムとファイルがキャッシュされ、古いブロックが削除されます。明らかに、メモリを大量に消費するワークロードもバッファキャッシュをクリアします。

于 2012-12-12T23:01:33.617 に答える
3

大量の小さなファイルを読み取っているため、プログラムはほとんどの時間、ディスクI/Oで待機するようにブロックされています。ディスクがデータを送信するのを待っている間、CPUはビジーではないため、100%よりも大幅に少ない負荷が発生しています。それが終わったら、今あなたはCPUに縛られており、あなたのプログラムは利用可能なすべてのCPU時間を消費します。

(Jarryd&DigitalRossが述べているように)システムメモリに読み込むと、OSのキャッシュにあるため、その後の読み込みは、そうでない限り、桁違いに速くなることがあります。他のディスクI/Oによって削除されました。したがって、プログラムを連続して実行する場合、2回目の実行はおそらくはるかに高速になります。しばらく待つと(そしてその間に他のことをする場合)、キャッシュからそれらのファイルを削除するのに十分な他のディスクI / Oがあった可能性があります。その場合、それらを再度読み取るのに長い時間がかかります。

于 2012-12-12T22:58:43.927 に答える
3

バッファキャッシュに言及している他の回答に加えて、コンパイル中に何が起こっているのかを理解したい場合は、以下のフラグのいくつかをGCCに渡すことができます(つまりg++、おそらくのCXXFLAGS設定としてMakefile):

  • -vg++関連するサブプロセスを表示するように要求する(たとえば、cc1plus適切なC ++コンパイラの場合)
  • -timeg++各サブプロセスの時間を報告するように依頼する
  • -ftime-reportg++(実際にはcc1plus)コンパイラ内の内部フェーズまたはパスの時間を報告するように依頼します。
于 2012-12-13T06:24:13.073 に答える