Optimiert die aktuelle JIT generierte Maschinencodes für die Verzweigungsvorhersage basierend auf Laufzeitstatistiken?

8

Einige JVMs kompilieren Java-Bytecode in nativen Maschinencode. Wir wissen, dass wir dafür viele Optimierungen anwenden können. Kürzlich habe ich auch erfahren, dass eine Verzweigungsoperation die CPU blockieren und die Leistung erheblich beeinträchtigen kann, wenn eine CPU eine falsche Vorhersage macht.

Weiß jemand, ob eine JVM Maschinencodes für die CPU einfacher generieren würde, um anhand der gesammelten Laufzeitstatistiken die richtige Vorhersage zu treffen?

William Wong
quelle
1
Ich denke, HotSpot macht das, aber auch die CPU verfügt seit Pentium II über eine dynamische Vorhersage-Technologie. Wenn sie also zweimal die falsche Entscheidung getroffen hat, korrigiert sie sich beim dritten Mal selbst, wenn sie den Kontext erkennt.
Aadaam

Antworten:

6

Nein, HotSpot fügt dem Hardwarezweig-Prädiktor keine Hinweise hinzu, wie in der OpenJDK-Mailingliste angegeben :

Es wurde in Betracht gezogen und dagegen entschieden. Die Plattformen, auf die openjdk derzeit abzielt, haben alle eine anständige bis spektakuläre Vorhersage für Hardwarezweige. Diejenigen, die dies nicht taten, wie Niagara 1, ignorierten Vorhersagebits. Die Schlussfolgerung ist, dass es sich nicht lohnt, den Code mit "magischen Makros" zu komplizieren, wie David sagt.

Rafael Winterhalter
quelle
OpenJDK ist kein HotSpot AFAIK.
Florian Margaine
Ja, so ist es. HotSpot ist die VM, die Teil des OpenJDK ist: openjdk.java.net/groups/hotspot
Rafael Winterhalter
Mein schlechtes dann. Ich dachte, HotSpot sei Suns VM, und OpenJDK sei eine Open-Source-Alternative.
Florian Margaine
2

Ich vermute, dass Vorhersagehinweise auf der Ebene der Maschinenbefehle bestenfalls ein Rauschen und im schlimmsten Fall ein Nachteil (verschwendete Befehlsbytes) für eine moderne, nicht in Ordnung befindliche, spekulativ ausführende Architektur sind. Dies wäre so, als würde man der CPU sagen, sie solle dumm sein - damit sie ihre bereits intelligenten Dinge nicht mehr tut, für die sie entwickelt wurde.


Zweitens hängt das Ausmaß, in dem die Verzweigungsvorhersage verbessert werden kann, von der Ursache der Fehlvorhersage und der Leichtigkeit ab, mit der man die Leistungseffekte der Verzweigung messen oder die Tendenz der Verzweigung beobachten kann.


Ich denke jedoch, dass die vorhandene Menge an JIT-Optimierungstricks die Verzweigungsvorhersage bereits bis zu einem gewissen Grad verbessern kann, auch ohne die Hilfe von Zählern für die falsche Vorhersage von CPU-Verzweigungen.

Nur ein sehr einfaches Codebeispiel:

public void repeatHistory(int value)
{
    if (value == 1492)
    {
        landing();
    }
    else if (value == 1776)
    {
        ratifying();
    }
}

Angenommen, das repeatHistorywird oft genannt. Wenn der auf Stichproben basierende Leistungsmonitor die Anrufstapelstatistik analysiert, kann er feststellen, dass repeatHistory()Anrufe aus irgendeinem Grund ratifying()häufiger auftreten als beim vorherigen Aufruf landing(). Basierend auf dieser Beobachtung wird dies beim nächsten Durchlauf der JIT-Codegenerierung für die repeatHistoryMethode berücksichtigt und eine oder mehrere Optimierungen durchgeführt:

  • Bewegen Sie den Scheck für (value == 1776)vor den Scheck für(value == 1492)
  • Versuchen Sie, die ratifying()Methode in den Zweig in zu integrierenrepeatHistory()
  • Wenn der repeatHistory()von einer anderen Schleife aufgerufen wird, versuchen Sie, die Schleife abzuwickeln, oder fügen Sie die repeatHistory()Methode in diese Schleife ein.
  • Und viele andere.

Nach dem Anwenden einer Optimierung muss häufig erneut analysiert werden, ob weitere Optimierungen angewendet werden können, da eine erfolgreiche Optimierung häufig die Tür zu mehr Möglichkeiten öffnet.


rwong
quelle