web-dev-qa-db-ja.com

CPUキャッシュ(C)を最適化する際に重要なことは何ですか?

these two questions を読んで、メモリ内の大量のデータを処理する場合、CPUキャッシュ動作を理解することが重要であることがわかります。キャッシングが最適化ツールボックスに別のツールを追加する方法を理解したいと思います。

CPUキャッシュを適切に使用するコードを記述できるように、CPUキャッシュが機能する方法のコアポイントは何ですか?関連して、不適切なキャッシュの使用が物事を遅くしているかどうかを確認するためにコードをプロファイルする方法はありますか?

13
Timothy Jones
17

この問題の複雑さは、最近の人間の理解を超えています。 (これは過去5年間でそのようになっています。)これをショートベクトル並列処理(SIMD)と組み合わせると、手作業でコードを最適化することが経済的に実現不可能であるという絶望的な感覚があります。不可能ではありませんが、費用対効果が高くない。

現在のアプローチは、最適化の方法をコンピューターに教えることに依存することです。異なる構造(ループ、データ構造、アルゴリズム)で同じ答えを計算するコードのバリエーションを作成し、パフォーマンスを自動的に評価します。コード変換のルールは非常に厳密な数学モデルで指定されているため、これはコンピューター科学者が理解でき、コンピューターで実行できるものです。

以下は Larry OBrien が投稿した answers のリンクです。

http://onward-conference.org/2011/images/Pueschel_2011_AutomaticPerformanceProgramming_Onward11.pdf

12
rwong

キャッシュを理解して最適化することは非常に可能です。それはハードウェアを理解することから始まり、システムを制御することで続行します。システムに対する制御が少ないほど、成功する可能性が低くなります。アイドリングではない一連のアプリケーション/スレッドを実行しているLinuxまたはWindows。

ほとんどのキャッシュはプロパティがいくらか似ています。アドレスフィールドの一部を使用してヒットを探し、深さ(ウェイ)、幅(キャッシュライン)を持っています。一部には書き込みバッファがあり、一部は書き込み時にキャッシュを介してまたはバイパスするように構成できます。

そのキャッシュにヒットしているすべてのメモリトランザクションを鋭敏に認識する必要があります(一部のシステムには、独立した命令とデータキャッシュがあり、タスクが容易になります)。

メモリを注意深く管理しないと、キャッシュを無用にすることができます。たとえば、処理中のデータブロックが複数あり、それらをキャッシュに保持することを期待しているが、キャッシュのヒット/ミスチェックに対して相対的に倍数であるアドレスのメモリにある場合、たとえば0x10000 0x20000 0x30000であり、さらに多くのこれらは、キャッシュ内の方法よりも、キャッシュをオンにした場合の動作が非常に遅くなり、キャッシュをオフにした場合よりも遅くなる可能性があります。しかし、それをおそらく0x10000、0x21000、0x32000に変更すると、キャッシュを十分に活用して追い出しを減らすのに十分な場合があります。

結論として、キャッシュを最適化するための鍵(システムを十分に理解していること以外は)は、パフォーマンスに必要なすべてのものを同時にキャッシュに保持し、データを整理できるようにすることです。すべてを一度にキャッシュに入れます。また、コード実行、割り込み、その他の定期的またはランダムなイベントなどが、使用しているこのデータの重要な部分を追い出すのを防ぎます。

コードについても同じことが言えます。ただし、キャッシュに保持したい他のコードとの衝突を避けるために、コードが存在する場所を制御する必要があるため、少し難しいです。キャッシュを通過するコードをテスト/プロファイリングするときに、コードのあちこちに1行または1つのnopを追加しますが、同じコードのコンパイル間でコードが存在するアドレスを別のコンパイルにシフトまたは変更するものは、キャッシュラインはそのコード内にあり、追い出されるものとクリティカルセクションにないものを変更します。

2
old_timer

nwong'sMichael Borgwardt's の両方の回答が良いアドバイスを与えます。

また、これらの問題に対するコンパイラの最適化を最初に信頼してください。

最近のGCCコンパイラーを使用している場合は、(節約と共に)__builtin_prefetch 関数。 stackoverflowの this answer を参照してください。