Ich erwarte ~ 100000 dTLB-Speicherfehler im Userspace, einen pro Iteration (auch ~ 100000 Seitenfehler und dTLB-Ladefehler für den Kernel). Wenn Sie den folgenden Befehl ausführen, ist das Ergebnis ungefähr das Doppelte, was ich erwarte. Ich würde mich freuen, wenn jemand klären könnte, warum das der Fall ist:
%Vor%P.S. Ich habe überprüft und bin sicher, dass der generierte Code nichts bringt, was dieses Ergebnis rechtfertigen würde. Außerdem bekomme ich ~ 100000 Seitenfehler und dTLB-Ladefehler: k.
Ich erwarte ~ 100000 dTLB-Speicherfehler im Userspace, einen pro Iteration
Ich würde das erwarten:
page[0] = 0;
zu laden, versucht die Cachezeile zu laden, die page[0]
enthält, kann den TLB-Eintrag nicht finden, erhöht dTLB-load-misses
, holt die Übersetzung, erkennt, dass die Seite "nicht vorhanden" ist, erzeugt dann einen Seitenfehler. INVLPG
). Der Seitenfehlerhandler kehrt zu dem Befehl zurück, der den Fehler verursacht hat, so dass er erneut versucht werden kann. page[0] = 0;
ein zweites Mal auszuführen, versucht die Cachezeile zu laden, die page[0]
enthält, kann den TLB-Eintrag nicht finden, erhöht dTLB-load-misses
, holt die Übersetzung und ändert dann die Cachezeile. Zum Spaß könnten Sie das MAP_POPULATE
-Flag mit mmap()
verwenden, um zu versuchen, den Kernel dazu zu bringen, die Seiten vorher zuzuweisen (und den Seitenfehler und den ersten TLB-Fehler zu vermeiden).
Update 2 : Ich denke, Brendans Antwort ist richtig. Ich sollte das vielleicht löschen, aber der ocperf.py
Vorschlag ist immer noch nützlich für zukünftige Leser, denke ich. Und es könnte zusätzliche TLB-Misses auf CPUs ohne Process-Context-Identifiers mit Kernels erklären, die Meltdown abschwächen.
Update : Die unten stehende Schätzung war falsch. Neue Vermutung: mmap
muss die Seitentabelle Ihres Prozesses ändern, also gibt es vielleicht eine TLB-Invalidierung von etwas gerade daraus. Meine Empfehlung, ocperf.py record
zu verwenden, um herauszufinden, welche asm-Anweisungen TLB-Misses verursachen, steht immer noch. Selbst wenn die Optimierung aktiviert ist, wird der Code auf dem Stapel gespeichert, wenn eine Rücksprungadresse für die Glibc-Wrapperfunktionsaufrufe gedrückt wird.
Vielleicht hat Ihr Kernel eine Kernel / User-Page-Table-Isolation aktiviert, um Meltdown abzuschwächen , also bei der Rückkehr vom Kernel Für den Benutzer wurden alle TLB-Einträge ungültig gemacht (indem CR3 geändert wurde, um auf Seitentabellen zu zeigen, die die Kernelzuordnungen überhaupt nicht enthalten).
Suchen Sie in Ihrer dmesg-Ausgabe nach Kernel/User page tables isolation: enabled
. Sie können versuchen, mit kpti=off
als Kerneloption zu booten, um sie zu deaktivieren, wenn es Ihnen nichts ausmacht, während des Tests anfällig für Meltdown zu sein.
Da Sie C verwenden, verwenden Sie die Systemaufrufe mmap
und munmap
über ihre Glibc-Wrapper, nicht direkt über die Inline-Anweisungen syscall
. Der Befehl ret
in diesem Wrapper muss die Rücksprungadresse vom Stapel laden, die der TLB nicht enthält.
Die zusätzlichen Speicherfehler kommen wahrscheinlich von call
Anweisungen, die eine Rücksprungadresse drücken, obwohl ich mir nicht sicher bin, dass die aktuelle Stapelseite bereits im TLB von ret
vom vorherigen Systemaufruf sein sollte.
Sie können Profile mit ocperf.py erstellen, um symbolische Namen für bestimmte Ereignisse zu erhalten. Angenommen, Sie befinden sich auf einer aktuellen Intel-CPU, ocperf.py record -e mem_inst_retired.stlb_miss_stores,page-faults,dTLB-load-misses
, um zu ermitteln, welche Anweisungen Speicherfehler verursachen. (Verwenden Sie dann ocperf.py report -Mintel
). Wenn report
es nicht einfach macht zu wählen, für welches Ereignis es zählt, nehmen Sie nur mit einem einzelnen Ereignis auf.
mem_inst_retired.stlb_miss_stores
ist ein "präzises" Ereignis, im Gegensatz zu den meisten anderen TLB-Speicherereignissen, also sollten die Zählungen für die echte Anweisung und nicht für spätere Anweisungen wie ungenaue Perf-Ereignisse gelten. (Siehe Andy Glews Trap vs. Exception-Antwort für einige Details darüber, warum einige Leistungsindikatoren nicht leicht präzise sein können, viele Speicherereignisse nicht.
Tags und Links c performance performancecounter tlb perf