2

PAPI 高レベル API を使用して、配列をループする単純なプログラムで TLB ミスをチェックしていますが、予想よりも大きな数が表示されます。

他の単純なテスト ケースでは、結果は非常に合理的であるように見えます。そのため、結果は本物であり、余分なミスはハードウェアのプリフェッチなどによるものだと思います。

誰かが数値を説明したり、PAPI の使用におけるエラーを指摘したりできますか?

int events[] = {PAPI_TLB_TL};
long long values[1];
char * databuf = (char *) malloc(4096 * 32);

if (PAPI_start_counters(events, 1) != PAPI_OK) exit(-1);
if (PAPI_read_counters(values, 1) != PAPI_OK) exit(-1); //Zeros the counters

for(int i=0; i < 32; ++i){
    databuf[4096 * i] = 'a';
}

if (PAPI_read_counters(values, 1) != PAPI_OK) exit(-1); //Extracts the counters

printf("%llu\n", values[0]);

印刷された数値は 32 の範囲、または少なくともその倍数であると予想しましたが、一貫して 93 以上の結果が得られます (一貫して 96 を超えるとは限りません。つまり、反復ごとに単純に 3 ミスするわけではありません)。他に何もないコアに固定して実行しています(タイマー割り込みを除く)。

私は Nehalem を使用しており、巨大なページを使用していないため、DTLB には 64 のエントリ (L2 には 512) があります。

4

2 に答える 2

5

コメントに基づいて:

  • を使用した場合、約 90 のミスが発生しmalloc()ます。
  • calloc()が使用されている場合、または配列が事前に繰り返されている場合は、32 のミス。

その理由は、遅延割り当てによるものです。OSは、実際に触れるまでメモリを提供していません。

最初にページに触れると、ページ フォールトが発生します。OS はこのページ フォールトをトラップし、オンザフライで適切に割り当てます (これにはとりわけゼロ化が含まれます)。これは、余分な TLB ミスの原因となっているオーバーヘッドです。

ただし、calloc()事前にすべてのメモリを使用またはタッチすると、このオーバーヘッドがカウンターを開始する前に移動します。したがって、結果は小さくなります。

残りの 32 回のミスについては…わかりません。
(または、コメントで述べたように、おそらく PAPI 干渉です。)

于 2013-02-19T16:09:42.983 に答える
0

これは、ループの反復ごとに4096ずつジャンプしていることが原因である可能性があります。

for(int i=0; i < 32; ++i){
    databuf[4096 * i] = 'a';
}

アクセスごとにキャッシュミスが発生する可能性が高くなります。

于 2013-02-19T16:06:53.440 に答える