私は人々がキャッシュの最適化をどのように行っているかを知りたいと思っており、この目標に向けた便利なツールとして友人から cachegrind を勧められました。
CPU シミュレーターである Valgrind は、 cachegrind を使用する場合、ここで説明されているように 2 レベルのキャッシュを想定しています。
Cachegrind は、プログラムがマシンのキャッシュ階層および (オプションで) 分岐予測子と対話する方法をシミュレートします。これは、独立した第 1 レベルの命令キャッシュとデータ キャッシュ (I1 および D1) を備えたマシンをシミュレートし、統合された第 2 レベルのキャッシュ (L2) に支えられています。これは、多くの最新のマシンの構成と正確に一致します。
次の段落は次のように続きます。
ただし、一部の最近のマシンには、3 レベルまたは 4 レベルのキャッシュがあります。これらのマシンの場合 (Cachegrind がキャッシュ構成を自動検出できる場合)、Cachegrind は最初のレベルと 最後のレベルのキャッシュをシミュレートします。この選択の理由は、最終レベルのキャッシュがメイン メモリへのアクセスをマスクするため、ランタイムに最も影響を与えるためです。
ただし、単純な行列 - 行列乗算コードで valgrind を実行しようとすると、次の出力が得られました。
==6556== Cachegrind, a cache and branch-prediction profiler
==6556== Copyright (C) 2002-2010, and GNU GPL'd, by Nicholas Nethercote et al.
==6556== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==6556== Command: ./a.out
==6556==
--6556-- warning: L3 cache detected but ignored
==6556==
==6556== I refs: 50,986,869
==6556== I1 misses: 1,146
==6556== L2i misses: 1,137
==6556== I1 miss rate: 0.00%
==6556== L2i miss rate: 0.00%
==6556==
==6556== D refs: 20,232,408 (18,893,241 rd + 1,339,167 wr)
==6556== D1 misses: 150,194 ( 144,869 rd + 5,325 wr)
==6556== L2d misses: 10,451 ( 5,506 rd + 4,945 wr)
==6556== D1 miss rate: 0.7% ( 0.7% + 0.3% )
==6556== L2d miss rate: 0.0% ( 0.0% + 0.3% )
==6556==
==6556== L2 refs: 151,340 ( 146,015 rd + 5,325 wr)
==6556== L2 misses: 11,588 ( 6,643 rd + 4,945 wr)
==6556== L2 miss rate: 0.0% ( 0.0% + 0.3% )
ドキュメントによると、L1 キャッシュと L3 キャッシュが使用されているはずですが、出力では L3 キャッシュが無視されていることが示されています。何故ですか?
また、cachegrind は、L1 および最終レベルのキャッシュ サイズを事前に想定していますか? それとも、現在実行されている CPU の L1 および最終レベルのキャッシュ サイズを使用しますか?