C++ プログラムを設計するときに起こりうるキャッシュ ミスの数を減らすにはどうすればよいですか?
インライン関数は毎回役に立ちますか? それとも、プログラムが CPU バウンドの場合 (つまり、プログラムが I/O 指向ではなく計算指向である場合) だけでよいのでしょうか?
この種のコードで作業するときに私が考慮したいことがいくつかあります。
データ バインド操作の場合
リスト、マップ、セットで配列とベクトルを使用する
行単位で列単位で処理
関数の実行をインライン化すると、命令キャッシュに損害を与えるリスクがあります。そして、メモリがフェッチバウンドでない場合、(もしあれば)大きな違いを生む可能性は低いです。
いつものように、最適化は、ハンチではなくプロファイリングによって通知する必要があります。言うまでもなく、プロファイラーが何を言っているかを理解する必要があります。これは、アセンブリ言語に精通していることと、最適化するプラットフォームの特定の特性を意味します。
今は少し古いですが、MikeAbrashの「Graphic'sProgrammingBlack Book」には、まだ多くの良い一般的なアドバイスがあります。
また、C++ とマルチスレッドを実行している場合は、各プロセッサのキャッシュ上のデータの偽共有、局所性、ホットネスを考慮する必要があります。それは大きな違いを生む可能性があります。また、特にマルチスレッドでは、LIFO 方式で計算する方が FIFO 方式で計算するよりも効率的ですが、シングル プロセッサ アーキテクチャでも有効です。
CPU がデータを効率的にプリフェッチできるようにします。たとえば、多次元配列を列ではなく行で処理したり、ループをアンロールしたりすることで、キャッシュ ミスの数を減らすことができます。
この種の最適化はハードウェア アーキテクチャに依存するため、Intel VTune などのプラットフォーム固有のプロファイラーを使用して、キャッシュで発生する可能性のある問題を検出することをお勧めします。
必要のない場合は、動的メモリの使用を避けてください。new、delete、スマートポインタなどを使用すると、プログラムデータがメモリ全体に分散する傾向があります。それは良いことではありません。(たとえば、スタック上のオブジェクトを宣言することによって)ほとんどのデータをまとめることができれば、キャッシュは確実にはるかにうまく機能します。