Warum gibt die JVM Prefetch-Anweisungen unter Windows x86 nicht aus?

8

Warum gibt die OpenJDK-JVM, wie der Titel sagt, eine Prefetch-Anweisung auf Windows x86 aus? Siehe OpenJDK Mercurial @ Ссылка

%Vor%

Es gibt keine Kommentare und ich habe außer dem Quellcode keine anderen Ressourcen gefunden. Ich frage, weil es so für Linux x86 tut, siehe Ссылка

%Vor%     
naze 04.06.2017, 14:34
quelle

2 Antworten

6

Die von Ihnen zitierten Dateien haben alle ein Asm-Code-Fragment ( Inline-Assembler ), das von einer C / C ++ - Software verwendet wird in seinem eigenen Code (als apangin, der JVM-Experte wies , meist in GC-Code). Und es gibt tatsächlich den Unterschied: Linux , Solaris und BSD Varianten von x86_64 Hotspot hat Prefetches im Hotspot und Windows hat sie deaktiviert / nicht implementiert, was teilweise seltsam ist, teilweise unerklärlichen warum, und es kann auch JVM-Bit (einige Prozent, mehr auf Plattformen ohne Hardware-Prefetch) unter Windows langsamer, aber immer noch nicht helfen um mehr solaris / solaris bezahlte Supportverträge für Sun / Oracle zu verkaufen. Ross auch geraten die Inline-ASM-Syntax wird möglicherweise nicht mit dem MS C ++ - Compiler unterstützt, aber _mm_prefetch sollte (Wer wird den JDK-Fehler öffnen, um ihn hinzuzufügen, zu der Datei ?).

JVM-Hotspot ist JIT, und der JITted-Code wird von JIT als Bytes ausgegeben (generiert). JIT kann zwar Code aus seinen eigenen Funktionen in generierten Code kopieren oder einen Aufruf an die Support-Funktionen ausgeben, Prefetch-Befehle werden jedoch ausgegeben als Bytes im Hotspot). Wie können wir herausfinden, wie es emittiert wird? Einfacher Online-Weg ist es, eine online durchsuchbare Kopie von jdk8u (oder besser in Querverweis wie Metager ) zu finden ), zum Beispiel auf github: Ссылка und suche nach prefetch oder prefetch emit oder prefetchr oder lir_prefetchr . Es gibt einige relevante Ergebnisse:

Tatsächliche Bytes, die in JVMs c1-Compiler / LIR in jdk8u_hotspot/src/cpu/x86/vm/assembler_x86.cpp :

%Vor%

Verwendung in c1 LIR: src/share/vm/c1/c1_LIRAssembler.cpp

%Vor%

Jetzt wissen wir den Opcode lir_prefetchr und können danach suchen oder in < a href="http://code.metager.de/source/search?q=lir_prefetchr&path=%2Fopenjdk%2Fjdk8%2F&project=openjdk"> OpenGrok xref und lir_prefetchw , um das einzige Beispiel in src/share/vm/c1/c1_LIR.cpp

%Vor%

Es gibt andere Stellen, an denen Prefetch-Anweisungen definiert sind (für C2, als von Apangin vermerkt, der src/cpu/x86/vm/x86_64.ad :

%Vor%     
osgx 04.06.2017, 16:21
quelle
7

Wie JDK-4453409 anzeigt, wurde der Vorabruf in HotSpot JVM in JDK 1.4 implementiert, um die Geschwindigkeit zu erhöhen GC. Das war vor mehr als 15 Jahren, niemand wird sich jetzt erinnern, warum es nicht unter Windows implementiert wurde. Meine Vermutung ist, dass Visual Studio (das seit jeher zum Erstellen von HotSpot unter Windows verwendet wurde) den Prefetch-Befehl zu diesen Zeiten grundsätzlich nicht verstanden hat. Sieht nach einem Ort für Verbesserungen aus.

Der Code, nach dem Sie gefragt haben, wird intern von JVM Garbage Collector verwendet. Dies erzeugt JIT nicht. Die Regeln für den C2-JIT-Codegenerator befinden sich in der Architekturdefinitionsdatei x86_64.ad , und es gibt Regeln , um die Knoten PrefetchRead , PrefetchWrite und PrefetchAllocation in die entsprechenden x64-Anweisungen zu übersetzen.

Eine interessante Tatsache ist, dass die Knoten PrefetchRead und PrefetchWrite nirgendwo im Code erstellt werden. Sie existieren nur, um Unsafe.prefetchX intrinsics zu unterstützen entfernt in JDK 9.

Der einzige Fall, in dem JIT Prefetch-Anweisungen generiert, ist PrefetchAllocation node. Sie können mit -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly überprüfen, dass PREFETCHNTA tatsächlich nach der Objektzuweisung generiert wird, sowohl unter Linux als auch unter Windows .

%Vor%

java.exe -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly Test

%Vor%     
apangin 04.06.2017 18:20
quelle

Tags und Links