2016-03-28 16 views
1

Ich bin nur eine Weile laufen 1 Schleife und Messung Cache-Miss.Cache fehlt in einer Endlosschleife ohne Speicherreferenzen?

int main() { 
    while(1); 
} 

Dieses spezielle Verfahren ist auf eine CPU-gebunden (mit taskset) und diese CPU isoliert ist, kann kein anderer Prozess bedeutet, auf der gleichen CPU geplant erhalten. Jetzt beginne ich mit der Messung der Cache-Performance unter Verwendung von perf und zu meiner Überraschung ist der letzte Level-Cache-Verlust 42%.

22,579  cache-references           (20.82%) 
8,976  **cache-misses   # 39.754 %** of all cache refs  (20.83%) 
4,414  **LLC-load-misses  # 42.74%** of all LL-cache hits 

Ich bin überrascht und ich erwarte Null-Cache-Miss, da ich keine Speicheroperation mache. Irgendwelche Hilfe/Gedanken dazu. CPU: Modellname: Intel (R) Xeon (R) CPU E5-2670 v3 @ 2.30GHz

Ein anderes Experiment, das ich mit einem Nano-Schlaf von .1 Millisekunden und Cache-Miss auf weniger als 1% reduziert. Ich habe keine Ahnung was los ist.

+0

Bedeutungsloser Code in, bedeutungslos ergibt sich. –

+0

Ich habe Gründe, dies zu tun. Ich versuche Cache-Probleme in einem großen Stück Code zu isolieren und schließlich stellt sich heraus, dass mein Code eine enge Schleife ist. Jetzt sehe ich, dass es einen Sprung im Cache-Miss gibt. Also entschied ich mich, eine einfache while-Schleife auszuprobieren und das Ergebnis überraschte mich. – deadbeef

+0

# 1: Sie können besser verstehen, was passiert, indem Sie den Asm-Code kompilieren. # 2 Ihr Beispiel ist wahrscheinlich zu einfach - Es wird nur auf eine Handvoll von Befehlen kompiliert, die nicht einmal * den Cache benutzen müssen - die Verzweigungsvorhersage wird immer * wissen *, was als nächstes zu tun ist, ohne auf irgendeinen Speicher zugreifen zu müssen. – tofro

Antwort

0

Wahrscheinlich zählen die Perf-Zähler einige Ereignisse aus Kernel-Code in Interrupt-Handlern. Perf-Counter-Events sind nicht präzise, ​​daher erhalten Sie Zählimpulse, die auf Befehle in der Nähe zurückzuführen sind, und ich vermute, dass Ops noch in der Pipeline sind, wenn der Kernel-Code eine iret gemacht hat. Oder dies kann Ereignisse im Kernel-Kontext vollständig zählen, da es bei jedem Interrupt teuer wäre, sich mit perf-counters zu messen.


Beachten Sie, dass der Cache-miss-Verhältnis nur schlecht aussieht, wenn Sie nicht berücksichtigen Sie, wie wenige Cache-Zugriffe gibt es insgesamt:

$ perf stat -e cycles,instructions,L1-dcache-loads,LLC-load-misses,LLC-loads,cache-references,cache-misses ./infloop 

Performance counter stats for './infloop': 

6,177,174,823  cycles              (28.79%) 
6,167,361,425  instructions    # 1.00 insns per cycle   (43.00%) 
    1,884,882  L1-dcache-loads            (42.93%) 
     13,133  LLC-load-misses   # 19.41% of all LL-cache hits  (42.75%) 
     67,676  LLC-loads              (28.74%) 
     391,004  cache-references            (28.50%) 
     18,025  cache-misses    # 4.610 % of all cache refs  (28.42%) 

    2.604227273 seconds time elapsed 

Timed auf einem Conroe Core2Duo E6600 (da ich mein Intel SnB-Motherboard mit Intels defekten BIOS-Updates gemauert).

cache-references und cache-misses sind "Kernel PMU Ereignisse" bezeichnet, während LLC-* und L1-* "Hardware-Cache-Events" sind nach perf list. Ich bin mir nicht sicher, was das bedeutet.

+1

Das ist richtig, wenn ich nur User Space Events vermesse, bekomme ich null.Die Cache-Verfehlungen stammen vom Kernel aufgrund von Timer-Interrupts – deadbeef