Ich versuche, eine genaue Messung des Speicherzugriff auf verschiedene Cache-Ebene zu machen, und kam mit diesem Code für das Sondieren bis:Genaue Speicherzugriffszeitprüfung mit RDTSC und RDTSCP?
__asm__ __volatile__(
"xor %%eax, %%eax \n"
"xor %%edi, %%edi \n"
"xor %%edx, %%edx \n"
/* time measurement */
"lfence \n"
"rdtsc \n"
"shl $32, %%rdx \n"
"or %%rdx, %%rax \n"
"movq %%rax, %%rdi \n"
/* memory access */
"movq (%%rsi), %%rbx\n"
/* time measurement */
"rdtscp \n"
"shl $32, %%rdx \n"
"or %%rdx, %%rax \n"
"movq %%rax, %%rsi \n"
"cpuid \n"
: /* output operands */
"=S"(t2), "=D"(t1)
: /* input operands */
"S" (mem)
: /* clobber description */
"ebx", "ecx", "edx", "cc", "memory"
);
jedoch der L1- und L2-Cache-Zugriff nur von 8 Zyklen unterscheiden, und den Ergebnissen sind zu viel schwank, so entschied ich mich, wie vielen Einfluss die umgebende Code (abgesehen von dem tatsächlichen Speicherzugriff) zu überprüfen, auf dem Timing hat:
__asm__ __volatile__(
"xor %%eax, %%eax \n"
"xor %%edi, %%edi \n"
"xor %%edx, %%edx \n"
/* time measurement */
"lfence \n"
"rdtsc \n"
"shl $32, %%rdx \n"
"or %%rdx, %%rax \n"
"movq %%rax, %%rdi \n"
/* memory access */
//"movq (%%rsi), %%rbx\n"
/* time measurement */
"rdtscp \n"
"shl $32, %%rdx \n"
"or %%rdx, %%rax \n"
"movq %%rax, %%rsi \n"
"cpuid \n"
: /* output operands */
"=S"(t2), "=D"(t1)
: /* input operands */
"S" (mem)
: /* clobber description */
"ebx", "ecx", "edx", "cc", "memory"
);
die Ergebnisse sahen wie folgt aus:
./cache_testing
From Memory: 42
From L3: 46
From L2: 40
From L1: 38
./cache_testing
From Memory: 40
From L3: 38
From L2: 36
From L1: 40
Ich bin mir bewusst, dass ich im Moment nicht die verschiedenen Cache-Ebenen nach Zweck abrufe, aber ich frage mich, warum das Timing im Falle des fehlenden Speicherzugriffs so stark schwankt. Der Code wird als SCHED_FIFO mit der höchsten Priorität ausgeführt, an eine CPU angeheftet und sollte während des Betriebs nicht gesendet werden. Kann mir jemand sagen, ob ich meinen Code und damit die Ergebnisse in irgendeiner Weise verbessern kann?
Die richtigen Zahlen für die Cache-Auslastung-> Nutzungslatenz bei Intel Haswell sind 4c für L1, 12c für L2, laut [Agner Fogs microarch pdf] (http://agner.org/optimize/). Eine gute Möglichkeit, dies zu messen (insbesondere für L1), ist das Posen-Jagen. Stellen Sie für L1 einfach einen Zeiger auf sich selbst und führen Sie 'mov (% rax),% rax 'in einer Schleife aus. Für L2 benötigen Sie eine große verkettete Liste, die nicht in L1 passt. –