L1D キャッシュ ミスをキャプチャできる単一のイベントがあるのではないかと考えています。最初にrdtscで特定のメモリにアクセスするまでのレイテンシを測定して、L1dのキャッシュミスを捉えてみました。私の設定では、L1d キャッシュ ミスが発生した場合、L2 キャッシュにヒットするはずです。そのため、RDTSC でメモリにアクセスする際のレイテンシを測定し、L1 キャッシュ レイテンシと L2 キャッシュ レイテンシと比較します。ただ、ノイズのせいでL1に当たったのかL2に当たったのか判別がつきません。そこで、RDPMC を使用することにしました。
パフォーマンス イベントを簡単に監視するための関数がいくつかの API に用意されていることがわかりましたが、RDPMC 命令をテスト プログラムで直接使用したいと考えています。MEM_INST_RETIRED.ALL_LOADS-MEM_LOAD_RETIRED.L1_HIT を使用して、L1D でミスしたリタイアしたロード命令の数をカウントできることがわかりました (PAPI_read_counters でL1 キャッシュ ミスをカウントすると、予期しない結果が得られます)。ただし、この投稿は papi Api について話しているようです。
特定のイベントをキャプチャするために rdpmc 命令を実行する前に、ecx レジスタに割り当てる必要がある値を見つけるにはどうすればよいですか?? また、以下のように、2 つの rdpmc 命令の間で 1 つのメモリ ロード命令に対して L1 ミスが発生したことを示す単一のイベントがあるかどうか疑問に思っています。
c = XXX; //I don't know what value should be assigned for what perf counter..
asm volatile(
"lfence"
"rdpmc"
"lfence"
"mov (0xdeadbeef), %%r10"//read memory
"mov %%eax, %%r10 //read lower 32 bits of counter
"lfence"
"rdpmc" //another rdpmc to capture difference
"sub %%r10, %%eax //sub two counter to get difference
:"=a"(a)
:"c"(c)
:"r10", "edx");
私は現在 9900k のコーヒー レイク マシンを使用しているので、インテルのマニュアルでコーヒー レイク マシンのパフォーマンス カウンター番号を検索しました。ロード命令の前後に MEM_LOAD_RETIRED.L1_HIT を 2 つキャプチャするだけでイベントをキャプチャできるようです。 ecx レジスタ。
最後に、rdpmc 命令を連続して行うにはシリアル化命令が必要なのだろうかと思います。私の場合、ロード命令だけを置いてL1dキャッシュミスが発生するかどうかを測定するため、最初のrdpmc命令をlfence命令で囲み、最後のrdpmcの前にもう1つのlfence命令を配置して、ロード命令が2番目のrdpmcの前に終了するようにします。
追加されたコード
asm volatile (
"lfence\n\t"
"rdpmc\n\t"
"lfence\n\t"
"mov %%eax, %%esi\n\t"
//measure
"mov (%4), %%r10\n\t"
"lfence\n\t"
"rdpmc\n\t"
"lfence\n\t"
"sub %%esi, %%eax\n\t"
"mov %%eax, (%0)\n\t"
:
:"r"(&perf[1]), "r"(&perf[2]), "r"(&perf[3]),
"r"(myAddr), "c"(0x0)
:"eax","edx","esi","r10", "memory");
また、コア番号 3 を isolcpu で固定し、テストのためにハイパースレッディングを無効にしました。MSRレジスタは以下のコマンドで計算されています
sudo wrmsr -p 3 0x186 0x4108D1 #L1 MISS