i386 Linux で。できれば c/(c/posix std libs)/proc にあることが望ましいです。そうでない場合、これを行うことができるアセンブリまたはサードパーティのライブラリはありますか?
編集:カーネルモジュールがキャッシュラインまたはプロセッサ全体をクリアするかどうかのテストを開発しようとしています(wbinvd()を使用)。プログラムはルートとして実行されますが、可能であればユーザー空間にとどまりたいです。
i386 Linux で。できれば c/(c/posix std libs)/proc にあることが望ましいです。そうでない場合、これを行うことができるアセンブリまたはサードパーティのライブラリはありますか?
編集:カーネルモジュールがキャッシュラインまたはプロセッサ全体をクリアするかどうかのテストを開発しようとしています(wbinvd()を使用)。プログラムはルートとして実行されますが、可能であればユーザー空間にとどまりたいです。
キャッシュコヒーレントシステムは、そのようなことをあなたから隠すために最善を尽くします. パフォーマンス カウント レジスタを使用してキャッシュ ミスを検出するか、メモリ位置を読み取る時間を高分解能タイマーで注意深く測定することにより、間接的に観察する必要があると思います。
このプログラムは、私の x86_64 ボックスで動作し、clflush
. を使用してグローバル変数を読み取るのにかかる時間を計りますrdtsc
。CPUクロックに直接結び付けられた単一の命令であるため、rdtsc
理想を直接使用できます。
81ティックかかりました 81ティックかかりました フラッシュ: 387 ティックかかりました 72ティックかかりました
3 つの試行が表示されます。最初の確認i
はキャッシュ内にあり (BSS の一部としてゼロにされただけなので、そうです)、2 番目はi
キャッシュ内にあるはずの読み取りです。次に、キャッシュからclflush
追い出さi
れ (近隣のキャッシュと共に)、再読み取りにかなりの時間がかかることが示されます。最終読み取りにより、キャッシュに戻っていることが確認されます。結果は非常に再現性が高く、キャッシュ ミスを簡単に確認できるほどの違いがあります。オーバーヘッドを調整したいrdtsc()
場合は、違いがさらに顕著になる可能性があります。
テストしたいメモリアドレスを読み取れない場合 (ただし、これらの目的mmap
に/dev/mem
は機能するはずです)、キャッシュラインのサイズとキャッシュの連想性を知っていれば、必要なものを推測できる場合があります。次に、アクセス可能なメモリの場所を使用して、関心のあるセット内のアクティビティを調べることができます。
#include <stdio.h>
#include <stdint.h>
inline void
clflush(volatile void *p)
{
asm volatile ("clflush (%0)" :: "r"(p));
}
inline uint64_t
rdtsc()
{
unsigned long a, d;
asm volatile ("rdtsc" : "=a" (a), "=d" (d));
return a | ((uint64_t)d << 32);
}
volatile int i;
inline void
test()
{
uint64_t start, end;
volatile int j;
start = rdtsc();
j = i;
end = rdtsc();
printf("took %lu ticks\n", end - start);
}
int
main(int ac, char **av)
{
test();
test();
printf("flush: ");
clflush(&i);
test();
test();
return 0;
}
キャッシュの状態を取得するための一般的なコマンドは知りませんが、方法はいくつかあります。
あなたはWBINVDについて言及しました-常に完全にフラッシュする、つまりすべてのキャッシュラインをフラッシュするafaik
特定の質問に対する回答ではないかもしれませんが、Cachegrindなどのキャッシュ プロファイラーを使用してみましたか? ユーザー空間コードのプロファイリングにのみ使用できますが、カーネル固有のインターフェイスに依存しない場合は、関数のコードをユーザー空間に移動するなど、それでも使用できる場合があります。
実際には、存在するかもしれないし存在しないかもしれない情報をプロセッサーに尋ねようとするよりも効果的かもしれません。それはおそらくあなたがそれについて尋ねるだけで影響を受けるでしょう-はい、ハイゼンベルクは彼の時代よりずっと前でした:-)