問題タブ [cachegrind]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
valgrind - cachegrind が完全に決定論的ではないのはなぜですか?
SQLite に触発されて、valgrind の「cachegrind」ツールを使用して、再現可能なパフォーマンス ベンチマークを行うことを検討しています。それが出力する数値は、私が見つけた他のどのタイミング方法よりもはるかに安定していますが、それでも決定論的ではありません. 例として、単純な C プログラムを次に示します。
これをコンパイルして cachegrind で実行すると、次の結果が得られます。
この場合、「I refs」は 2 回の実行で 0.008% しか違わないのですが、なぜこれらが異なるのか疑問に思っています。より複雑なプログラム (数十ミリ秒) では、さらに異なる場合があります。実行を完全に再現可能にする方法はありますか?
c++ - cachegrind: キャッシュサイズを設定
cachegrind を使用して、さまざまなキャッシュ サイズでプログラムのパフォーマンスをテストしようとしています。コマンドの最後のレベルのキャッシュ サイズを設定するにはどうすればよいですか? (フラグ --LL を使用する必要があると読みましたが、機能しません。コマンドの例を教えてください。)
どうもありがとうございました!
c - プログラムの速度低下が CPU キャッシュの問題であるかどうか (Linux の場合) を特定するにはどうすればよいですか?
私は現在、私の C プログラムの 1 つで非常に奇妙な動作を理解しようとしています。どうやら、一見取るに足らない行を最後に追加または削除すると、プログラムの残りの部分のパフォーマンスに大きな影響を与えるようです。
私のプログラムは次のようになります。
理論的にfclose(input)
は、OS はプログラムの最後でファイルを自動的に閉じる必要があるため、main 関数の最後の行は重要ではありません。ただし、fclose ステートメントを含めた場合はプログラムの実行に 2.5 秒かかり、コメントアウトした場合は 5 秒かかりました。2倍の差!これは、プログラムの開始時または終了時の遅延によるものではありません。出力される速度は.
、fclose ステートメントを使用したバージョンの方が目に見えて高速です。
これは、メモリ アライメントまたはキャッシュ ミスの問題に関係している可能性があると思われます。fclose を ftell などの別の関数に置き換えると、実行に 5 秒かかり、要素のサイズlarge_buffer
を <= 8000 要素に減らすと、fclose ステートメントがあるかどうかに関係なく、常に 2.5 秒で実行されます。
しかし、この奇妙な動作の背後にある犯人が何であるかを 100% 確信できるようにしたいと考えています。私のプログラムをある種のプロファイラーまたはその情報を提供する他のツールで実行することは可能でしょうか? これまでのところ、両方のバージョンを実行してみましvalgrind --tool=cachegrind
たが、プログラムの両方のバージョンで同じ量のキャッシュ ミス (0%) が報告されました。
編集1:私のプログラムの両方のバージョンを実行した後perf stat -d -d -d
、次の結果が得られました:
kcachegrind が報告したように、どちらの場合もデータ キャッシュ ミスはほとんどないように見えますが、遅いバージョンのプログラムでは分岐予測が悪化し、命令キャッシュ ミスと iTLB ロードが多くなりました。これらの違いのうち、テスト ケース間の実行時間の 2 倍の違いの原因となる可能性が最も高いのはどれですか?
編集 2: おもしろい事実ですが、「fclose」呼び出しを単一の NOP 命令に置き換えても、奇妙な動作を維持できるようです。
編集 3: 私のプロセッサは Intel i5-2310 (Sandy Bridge) です
編集 4: アセンブリ ファイルを編集して配列のサイズを変更すると、高速にならないことがわかりました。C コードでサイズを変更したときに高速になった理由は、gcc がバイナリ内のものの順序を再配置することを決定したためだと思われます。
編集 5: 重要なのは JMP 命令の正確なアドレスであるというさらなる証拠: コードの先頭に単一の NOP (printf の代わりに) を追加すると、高速になります。同様に、コードの先頭から不要な命令を削除すると、速度も向上します。また、別のバージョンの gcc でコードをコンパイルすると、生成されたアセンブリ コードは同じであるにもかかわらず、高速になりました。唯一の違いは、最初のデバッグ情報と、バイナリ ファイルのセクションの順序が異なっていたことです。
c++ - Cachegrind: キャッシュミスが多いのはなぜですか?
私は現在、Linux でのさまざまなプロファイリングおよびパフォーマンス ユーティリティ、特に valgrind/cachegrind について学んでいます。
私は次のおもちゃのプログラムを持っています:
このプログラムを でコンパイルしg++ -O2 -g main.cpp
て実行するとvalgrind --tool=cachegrind ./a.out
、cg_annotate cachegrind.out.31694 --auto=yes
次の結果が生成されます。
私が心配しているのは、この行です:
この行にキャッシュミスが多いのはなぜですか? データは連続したメモリにあり、各反復で 64 バイトのデータを読み取ります (キャッシュ ラインの長さが 64 バイトであると仮定します)。
このプログラムは、Ubuntu Linux 18.04.1、カーネル 4.19、g++ 7.3.0 で実行しています。パソコンはAMD2400Gです。
valgrind - 空間的または時間的な局所性のためにキャッシュ ラインが再利用されているかどうかを検出する
空間的または時間的な局所性のためにキャッシュラインが再利用されている (キャッシュミスが回避されている) かどうかを検出する実用的なツールはありますか?
cachegrindで関連する議論が見つかりませんでした。thisおよびthis paperのみを見つけることができましたが、それらで紹介されているツールは見つかりませんでした。
performance - 実行時間を確定的に見積もる
x86-64 マシン コードにコンパイルする C++ 関数があり、特定の入力での実行時間を測定したいと考えています。コードを変更するとパフォーマンスが低下する時期を知りたいので、このベンチマークを CI で実行し、関数の実行に最大 X ミリ秒かかることをテストします。
ただし、実行時間は非決定論的であるため、そのようなテストは不安定になります。
このテストを決定論的にするために使用できるツールはありますか? そのようなツールは、エミュレーターでコードを実行し、ヒューリスティックを使用して合計を概算することにより、(特定のクロック レートで特定の CPU モデル上で、特定の RAM クロック/レイテンシで) 実行時間の決定論的な見積もりを提供すると想像します。実行時間。
(単純なヒューリスティックは、リタイアしたマシン命令をカウントし、命令ごとに Y ns を想定することですが、より洗練されたアプローチでは、メモリ アクセスを調べてキャッシュ ヒット/ミスをモデル化することもできます。そのようなツールを使用できなかった技術的な理由はわかりません。最新の CPU アーキテクチャの複雑さと、それらがサポートする命令セットのサイズを考えると、正確に近い推定値を取得するものを書くのは難しいということを除けば、存在しません。)
profiling - valgrind の cachegrind は 2021 年も依然として頼りになるツールですか?
私はプログラムのプロファイリングに cachegrind を長年使用しており、最近公式ドキュメントをもう一度チェックするために戻ってきました: https://valgrind.org/docs/manual/cg-manual.html
その中には、すべて 2000 年代半ばの CPU モデル、実装決定、およびシミュレーション モデルへの複数の参照があり、「最新の」プロセッサでは一部の動作が変更されたという記述もあります。
通常、LL キャッシュは L1 キャッシュのすべてのエントリを複製します [...] これは Pentium チップでは標準ですが、AMD Opterons、Athlon、Durons は排他的な LL キャッシュを使用します [...]
Cachegrind は、2004 年頃の主流のデスクトップ/サーバー プロセッサの典型的なブランチ プレディクタをシミュレートします。
最近のプロセッサはより優れた分岐予測子を備えています [...] Cachegrind の予測子の設計は、より洗練された間接分岐予測子の広範な展開に先立つ大規模なインストール ベースのプロセッサを代表するように、意図的に保守的です。特に、最新モデルの Pentium 4s (Prescott)、Pentium M、Core、および Core 2 には、Cachegrind によってモデル化されたよりも洗練された間接分岐予測子があります。
今、私は疑問に思っています
- 最新世代の CPU で開発する場合、これらの選択肢のうちいくつが 2021 年に適用されるか、
- cachegrind の実装は最新の CPU を反映するように更新されているが、マニュアルは古くなっているかどうか、
- 従来の動作のシミュレーションにより、最新の CPU で cachegrind が歪んだ結果を示すかどうか。
どんな洞察も大歓迎です!