PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : optimierender Java Compiler


elianda
2006-10-18, 11:02:27
Hallo,

ich habe mal nach einem Vergleich zwischen Java Compilern gesucht und habe nur steinalte Vergleiche gefunden.
Der Hintergrund ist, dass es mit dem Masseneintritt von Mehrprozessorsystemen in den Markt Intel da ziemlich viel Aufwand in ihren C bzw. Fortran Compiler steckt. zB. mit automatischen aufsplitten von Schleifen usw.


Wie sieht es denn aktuell auf diesem Feld bei Java aus?
Hat jemand Erfahrung mit dem GCJ ?

Simon
2006-10-18, 11:23:50
Bei uns lief mal eine Studienarbeit zu dem Thema: Klick mich (http://ausbildung.rus.uni-stuttgart.de/projekte-2005.html#bluemchen-projekt-05)
Hat leider keine Multi CPU-Tests drin, glaub ich ...

Abnaxos
2006-10-18, 11:25:14
Es gibt keine optimierenden Java-Compiler (mehr). Zur Compile-Time ist einfach zu wenig über das Zielsystem bekannt, als dass es Sinn machen würde, bereits dann optimieren zu wollen, der Schuss könnte sogar nach hinten los gehen.

Die Optimierung wird von der JVM zur Laufzeit wesentlich effizienter erledigt, da die JVM das Zielsystem exakt kennt (es ist das, wo sie gerade drauf läuft) und auch noch das dynamische Laufzeitverhalten des Programms in die Optimierungen mit einbeziehen kann.

Da stecken einige Jahre Forschung drin, HotSpot und die anderen JITs machen das schon gut ... ;)

Senior Sanchez
2006-10-18, 11:29:30
@Abanaxos Jap.

Wobei ich mich auch Frage, ob automatisches Multi-Threading in der Praxis (von irgendwelchen synthetischen Benchmarks abgesehen), wirklich soviel bringt, weil im Grunde ja automatisch höchstens nen paar Schleifen optimiert werden können.
Alles was dann darüber hinaus geht, ich sag mal echte Lastverteilung durch verschiedene Threads die unabhängig voneinander arbeiten und sich öfters synchronisieren, ich weiß nicht, ich glaube das geht automatisch nicht und ich meine, dass so etwas erst wirklich Performanceverbesserungen bringt.

PatkIllA
2006-10-18, 11:31:20
@abmaxos
so Sachen wie toten (oder faulen) Code entfernen kann man schon sinnvoll machen.
Ich hab das mal an der Uni gemacht. Ergebnis war aber auch, dass es nur in den Fällen was gebracht hat, wo wir extra schlechten Code geschrieben haben ;)

Senior Sanchez
2006-10-18, 11:34:30
@abmaxos
so Sachen wie toten (oder faulen) Code entfernen kann man schon sinnvoll machen.
Ich hab das mal an der Uni gemacht. Ergebnis war aber auch, dass es nur in den Fällen was gebracht hat, wo wir extra schlechten Code geschrieben haben ;)

Naja, setzt man ne gute IDE ein, braucht man dafür keinen speziellen Compiler ;)
IDEA weißt auf sowas auch hin oder, Abanaxos? ;)

PS: Apropos IDEA:
Es ist schon der Wahnsinn, was diese IDE leistet und das Motto, Develop with Pleasure, ist echt super gewählt.

Ich baue z.B. öfters checks auf null ein. IDEA weißt mich dann dabei öfters daraufhin, dass die Variable eh nie null sein kann, indem es den Aufrufbaum während man gerade coded hinaufgeht und Rückgabewerte prüft usw. Das finde ich schon stark.
Oder ich habe sonen kleinen endlos-thread geschrieben (mit Absicht, weil ich die Funktion brauche) - IDEA weißt dann daraufhin, dass der Thread nie normal beendet werden kann und sich an manchen Stellen eventuell ein Busy-Waiting einstellt.

Shink
2006-10-18, 11:53:56
Hallo,

ich habe mal nach einem Vergleich zwischen Java Compilern gesucht und habe nur steinalte Vergleiche gefunden.
Der Hintergrund ist, dass es mit dem Masseneintritt von Mehrprozessorsystemen in den Markt Intel da ziemlich viel Aufwand in ihren C bzw. Fortran Compiler steckt. zB. mit automatischen aufsplitten von Schleifen usw.


Wie sieht es denn aktuell auf diesem Feld bei Java aus?
Hat jemand Erfahrung mit dem GCJ ?
Hab Erfahrung mit dem GCJ - empfehlen kann ich ihn aber nicht wirklich: Schneller wird damit höchstens die Startup-Time.

Wenn man tatsächlich seine Java-Programme nativ compilen will, um einen Geschwindigkeitszuwachs zu bekommen, kann ich nur von Excelsior JET sagen, dass es einiges bringt - ausser man lädt Klassen dynamisch (z.B. Eclipse).

UliBär
2006-10-18, 13:14:26
Es gibt keine optimierenden Java-Compiler (mehr). Zur Compile-Time ist einfach zu wenig über das Zielsystem bekannt, als dass es Sinn machen würde, bereits dann optimieren zu wollen, der Schuss könnte sogar nach hinten los gehen. (...)Das ist richtig in Bezug auf plattformspezifische Optimierungen. Den Code selbst optimieren kann ein Java-Compiler aber schon, z. B. Schleifeninvarianzen herausziehen, Loop-unrolling, usw. Moderne Compiler machen das eigentlich alle, inklusive der GCC Implementationen.

Abnaxos
2006-10-18, 14:01:34
Das ist richtig in Bezug auf plattformspezifische Optimierungen. Den Code selbst optimieren kann ein Java-Compiler aber schon, z. B. Schleifeninvarianzen herausziehen, Loop-unrolling, usw.

Eben nicht. Natürlich könnte ein Java-Compiler ein Loop-Unrolling machen, nur tut er es nicht, weil er nicht wissen kann, ob das auf der endgültigen Plattform überhaupt eine gute Idee ist. Vielleicht läuft das Programm ja unter einer CPU, die Loops unheimlich effizient ausführen kann und ein Loop-Unrolling zieht ihr nur den Boden für ihre eigenen Optimierungen unter den Füssen weg. Wenn der Compiler das bereits macht, nimmt er der JVM einfach die Entscheidungsfreiheit, so zu optimieren, wie es für die aktuelle Plattform am besten ist, das ist alles, was ein optimierender Java-Compiler erreicht. Im besten Fall macht's keinen Unterschied, im schlimmsten Fall ging der Schuss nach hinten los.

Zudem muss man aufpassen: Es können einzelne Klassen ersetzt werden, möglicherweise sogar zur Laufzeit, was massive Auswirkungen darauf haben kann, wie optimiert werden soll. Ein Java-Compiler kann das nicht im voraus wissen und kümmert sich daher nicht darum.

HotSpot dagegen sieht das zur Laufzeit und reagiert entsprechend. Er geht dabei recht weit: Hat eine Klasse A eine public Methode x() und von A wird keine weitere Klasse abgeleitet, kann HotSpot entscheiden, x() zu inlinen. Wird nun später zur Laufzeit eine Klasse B geladen, die von A erbt und x() überschreibt, wird HotSpot das wieder rückgängig machen.

Möglicherweise wird die Klasse B später wieder weggeworfen und eine Klasse C (oder gar eine andere Version der Klasse B) nachgeladen, die x() nicht überschreibt => HotSpot kann wieder inlinen.

Ein Java-Compiler kann unmöglich bereits zur Compile-Time entscheiden, wie das Programm zur Laufzeit aussieht und was auf der aktuellen Plattform für Optimierungen sinnvoll sind.

Moderne Compiler machen das eigentlich alle, inklusive der GCC Implementationen.

Java-Compiler nicht. Es gibt eine einzige Ausnahme, die in der JLS idiotischerweise definiert ist, weil ein paar Leute nach bedingter Kompilierung geschrien haben: Toter Code durch eine If-Abfrage auf eine Boolean-Konstante oder ein Boolean-Literal, das false ist, muss entfernt werden (JLS §14.21).

UliBär
2006-10-18, 14:28:57
Quelle?

Abnaxos
2006-10-18, 15:29:49
Quelle?

Uff, viele. Was HotSpot alles macht, kannst du in beliebigen technischen Artikeln dazu nachlesen. Und nicht nur HotSpot macht diese Sachen, jede JVM mit akzeptabler Performance tut das, die einen besser, die anderen schlechter. Die .NET CLI natürlich auch.

Die gute alte Wikipedia hat eine Zusammenfassung (http://de.wikipedia.org/wiki/Hotspot-Optimierung), ein vollständig(er)es Dokument von Sun findest du bei usenix.org (http://www.usenix.org/events/jvm01/full_papers/paleczny/paleczny.pdf).

Seit JDK 1.2 ist das -O-Flag (optimise) von javac wirkungslos und nur noch vorhanden, damit alte Makefiles nicht kaputt gehen. Dazu gibt es viele Untersuchungen, die aufzeigen, dass dynamische Compiler aus den genannten Gründen grundsätzlich schnelleren Code erzeugen können als statische Compiler (da gab's doch mal so ein Experiment, wo man Maschinen-Code statisch optimiert direkt auf die CPU losgelassen hat, und denselben unoptimierten Code in einer VM, die nach den Prinzipien von HotSpot funktioniert => die VM war schneller).

UliBär
2006-10-18, 17:34:55
@Abnaxos: Danke für die Info, man lernt nie aus... :uup:

HellHorse
2006-10-18, 23:19:34
.....
HotSpot dagegen sieht das zur Laufzeit und reagiert entsprechend. Er geht dabei recht weit: Hat eine Klasse A eine public Methode x() und von A wird keine weitere Klasse abgeleitet, kann HotSpot entscheiden, x() zu inlinen. Wird nun später zur Laufzeit eine Klasse B geladen, die von A erbt und x() überschreibt, wird HotSpot das wieder rückgängig machen.
Das stimmt zwar liesse sich aber auch vermeiden wenn man type-feedback hätte wie z.B StrongTalk. Dann reicht eigentlich ein jump + branch und den lookup kann man sich schenken.

Zudem kann ja auch zur Klassenladezeit (:ugly:) viel kranke Scheisse abgehen, Stichwort AOP.

Köppchen
2006-10-19, 23:33:05
Auch an den jvm's wird weiterentwickelt.
Ich hatte z.B. letztens gelesen das beim Java im Websphere 6.1 (ibm jvm) der jit Compiler in einem eigenen Thread arbeitet. Vorher lief der jit Compiler immer syncron.

Gruß Markus

ollix
2006-10-20, 10:06:13
Java-Compiler nicht. Es gibt eine einzige Ausnahme, die in der JLS idiotischerweise definiert ist, weil ein paar Leute nach bedingter Kompilierung geschrien haben: Toter Code durch eine If-Abfrage auf eine Boolean-Konstante oder ein Boolean-Literal, das false ist, muss entfernt werden (JLS §14.21). Was spricht denn dagegen?

Abnaxos
2006-10-20, 11:11:58
Es ist eine unnötige Fehlerquelle. Wenn ich so eine Boolean-Konstante von false auf true ändere, muss ich daran denken, das gesamte Programm neu zu compilieren. Wenn es eine Library war, muss ich alle Programme, die diese Library benutzen, neu compilieren.

Das gilt leider generell für Konstanten, d.h. die JLS verlangt, dass alles, was public static final ist und dessen Wert zur Compile-Time bekannt ist, direkt eincompiliert wird. Design-Fehler, IMHO, aber jetzt kann man's nicht mehr ändern, dafür ist es zu spät ... :(