"Runtime Overhead" durch Virtuele Maschinen (Java/.net) in Zeiten von Just in Time Compilern und modernen CPUs
-
C++ vs. Java/C#, das hatten wir ja schon mindestens 1 Woche nicht mehr. Gähn.
-
Also ich hab' grade ein mehrwöchiges Duell mit einem guten Freund, es geht uns
dabei um die Entwicklung einer UCI Schach-Engine.
Mein Freund wird für seine Engine ein stark objektorientiertes Design + JAVA
verwenden,
während ich zeitgleich eine (antiquierte, nativ-kompilierte) C-Engine bastle
(die zu allem Überdruss auch nicht sonderlich objektorientert ist).
Er wird dann versuchen, mit seiner OOP-JAVA-JIT Engine meine altbackene C-Engine
in einem mehrrundigen Blitz-(5 min.)-Wettkampf zu besiegen.
Natürlich haben wir gleichzeitig mit der Programmierung (Ende Dezember) begonnen, Deadend wäre der 1.März 2011.Werde mich gerne im März wieder melden, um vom Ausgang unseres kleinen Wettstreits:
-----------------------------
OOP+JAVA+JIT
vs.
Prozedural+C+Nativ-Kompiliert
-----------------------------
Thema: (UCI-)Schach-Engine
-----------------------------zu berichten.
Wetten/Prognosen auf den mutmaßlichen Sieger werden ab sofort angenommen !
(Wie auch immer es ausgehen wird - wir geben beide unser Bestes!
Inwieweit man dann daraus die richtigen Rückschlüsse auf die Über-/Unterlegenheit des JAVA-JIT-Compilers gegenüber dem nativen C-Compiler
ziehen wird können, wissen wohl nur die Experten ...)
-
Compet schrieb:
(Wie auch immer es ausgehen wird - wir geben beide unser Bestes!
Inwieweit man dann daraus die richtigen Rückschlüsse auf die Über-/Unterlegenheit des JAVA-JIT-Compilers gegenüber dem nativen C-Compiler
ziehen wird können, wissen wohl nur die Experten ...)wennst dich zocken lässt, hack ich dir die finger ab
-
Compet schrieb:
Also ich hab' grade ein mehrwöchiges Duell mit einem guten Freund, es geht uns
dabei um die Entwicklung einer UCI Schach-Engine.
Mein Freund wird für seine Engine ein stark objektorientiertes Design + JAVA
verwenden,
während ich zeitgleich eine (antiquierte, nativ-kompilierte) C-Engine bastle
(die zu allem Überdruss auch nicht sonderlich objektorientert ist).
Er wird dann versuchen, mit seiner OOP-JAVA-JIT Engine meine altbackene C-Engine
in einem mehrrundigen Blitz-(5 min.)-Wettkampf zu besiegen.
Natürlich haben wir gleichzeitig mit der Programmierung (Ende Dezember) begonnen, Deadend wäre der 1.März 2011.Werde mich gerne im März wieder melden, um vom Ausgang unseres kleinen Wettstreits:
-----------------------------
OOP+JAVA+JIT
vs.
Prozedural+C+Nativ-Kompiliert
-----------------------------
Thema: (UCI-)Schach-Engine
-----------------------------zu berichten.
Wie spielen die gegeneinander?
-
-> Mit der GUI von Fritz 11 (Dort kann man UCI-Engines gegeneinander spielen
lassen)
-
Vorweg: Ich kenne beide Seiten, habe 7 Jahre lang hauptsächlich Java programmiert und dann für meine jetzten "number chrunching"-Anwendungen auf C++ gewechselt (seit 3 Jahren).
Das mit den JIT-Compilern ist schon toll. Aber das relativ hohe Abstraktionsniveau der Virtual Machine und all das "definierte Verhalten" dürfte sich immer noch negativ auf die Performance auswirken. Da gibt es zum einen speicherfressende Eigenschaften, um Dinge wie Reflection zu ermöglichen, auch wenn man so etwas in einem konkreten Fall gar nicht braucht. Und zum anderen gibt es Bremsen wie Nullzeiger-Checks, Array-Index-Checks, Erzwungenes Late-Binding (gut, das lässt sich größtenteils durch "final" reduzieren) und die Tatsache, dass man eben alle Objekte dynamisch anlegen muss und sich dabei kaum um Dinge wie Cache-Lokalität kümmern kann.
In C++ bist Du einfach näher an der Maschine - JIT hin oder her.
-
Compet schrieb:
Wetten/Prognosen auf den mutmaßlichen Sieger werden ab sofort angenommen !
Die Wette geht an den besseren Programmierer... Nach meiner Erfahrung hat die Wetware immer noch den größten Einfluß auf das Ergebnis. Oder anders formuliert: Man kann auch in C langsame Programme schreiben...
-
Wenn OpenGl z.B. fuer CAD-Software benutzt wird, dann wuerde ich eine compilierte Sprache vorziehen. Im besonderen Fall von Java mache ich mich zusaetzlich von Oracle abhaengig, vielleicht bekommt man spaeter nur die Jit-Engine beim Kauf einer Lizenz. Das waere schlecht. Weiterhin bekommt man Jit meist nur fuer x86-Plattformen, will man fuer etwas anderes entwickeln, so wird es schwierig.
-
Compet schrieb:
Also ich hab' grade ein mehrwöchiges Duell mit einem guten Freund, es geht uns
dabei um die Entwicklung einer UCI Schach-Engine.
Mein Freund wird für seine Engine ein stark objektorientiertes Design + JAVA
verwenden,
während ich zeitgleich eine (antiquierte, nativ-kompilierte) C-Engine bastle
(die zu allem Überdruss auch nicht sonderlich objektorientert ist).
Er wird dann versuchen, mit seiner OOP-JAVA-JIT Engine meine altbackene C-Engine
in einem mehrrundigen Blitz-(5 min.)-Wettkampf zu besiegen.
Natürlich haben wir gleichzeitig mit der Programmierung (Ende Dezember) begonnen, Deadend wäre der 1.März 2011.Werde mich gerne im März wieder melden, um vom Ausgang unseres kleinen Wettstreits:
-----------------------------
OOP+JAVA+JIT
vs.
Prozedural+C+Nativ-Kompiliert
-----------------------------
Thema: (UCI-)Schach-Engine
-----------------------------zu berichten.
Wetten/Prognosen auf den mutmaßlichen Sieger werden ab sofort angenommen !
(Wie auch immer es ausgehen wird - wir geben beide unser Bestes!
Inwieweit man dann daraus die richtigen Rückschlüsse auf die Über-/Unterlegenheit des JAVA-JIT-Compilers gegenüber dem nativen C-Compiler
ziehen wird können, wissen wohl nur die Experten ...)Was fürn Quatsch.
Wer gewinnt wird doch nicht durch die Programmiersprache entschieden, sondern nur durch die KI Algorithmen. D.h. wer den besseren Gegner schreibt.
Vergleichbar wird das doch nur, wenn der Gegner genau gleich gut implementiert wird, aber dann die Denkzeiten zur Entscheidungsfindung für die Spielzüge der begrenzende Rahmen sind.
DANN kommt es nämlich wirklich darauf an, welche Sprache schneller die letzten endes richtige Entscheidung findet, bevor die Zugzeit abgelaufen ist.
-
Mein Tipp:
Bei so rechen-intensiven Anwendungen wie Schach spielen Dinge wie kluges
Caching, 64-Bit-Bitboard Operationen u.ä. eine derart vordergründige Rolle,
dass Dein Java-Freund auch bei noch so exzellenter, objektorientierter
Programmierung gegen eine 'reine', nativ kompilierte C Engine (die auch
weitestgehend die selben Algorithmen implementieren müsste (um überhaupt
vergleichbar zu sein!)) keine Chance haben dürfte und idR nicht annähernd an
die üblichen Suchtiefen eines C/C++ Schachprogramms herankommen wird.
Allgemein vermute ich, dass bei so rechenintensiven Problemstellungen
wie Schach (aber-trillionen mögliche Folgestellungen schon nach wenigen
Zügen) wohl auch C++ wegen dem Overhead mit den Containern nicht gut brauchbar
ist und erheblich schlechter als C abschneiden dürfte.
Bei solchen hochperformanten Sachen führt wohl einfach kein Weg an C vorbei,
weil damit kann man dann auch noch jede Schleife manuell entrollen usw.
um auch wirklich noch die allerletzte Nano-Sekunde an Performance rauszuholen.
Wünsche trotzdem Euch beiden viel Glück mit Euren Projekten
Und vielleicht könnt ihr die Resultate dann ja auch zum Ausprobieren ins Netz
stellen (am besten mit Quell-Code).
mfg
-
Experte65 schrieb:
Mein Tipp:
Bei so rechen-intensiven Anwendungen wie Schach spielen Dinge wie kluges
Caching, 64-Bit-Bitboard Operationen u.ä. eine derart vordergründige Rolle,
dass Dein Java-Freund auch bei noch so exzellenter, objektorientierter
Programmierung gegen eine 'reine', nativ kompilierte C Engine (die auch
weitestgehend die selben Algorithmen implementieren müsste (um überhaupt
vergleichbar zu sein!)) keine Chance haben dürfte und idR nicht annähernd an
die üblichen Suchtiefen eines C/C++ Schachprogramms herankommen wird.
Allgemein vermute ich, dass bei so rechenintensiven Problemstellungen
wie Schach (aber-trillionen mögliche Folgestellungen schon nach wenigen
Zügen) wohl auch C++ wegen dem Overhead mit den Containern nicht gut brauchbar
ist und erheblich schlechter als C abschneiden dürfte.
Bei solchen hochperformanten Sachen führt wohl einfach kein Weg an C vorbei,
weil damit kann man dann auch noch jede Schleife manuell entrollen usw.
um auch wirklich noch die allerletzte Nano-Sekunde an Performance rauszuholen.
Wünsche trotzdem Euch beiden viel Glück mit Euren Projekten
Und vielleicht könnt ihr die Resultate dann ja auch zum Ausprobieren ins Netz
stellen (am besten mit Quell-Code).
mfgTja, die Nanosekunden bringen halt garnix, sondern nur der bessere Algorithmus gewinnt.
-
Experte65 schrieb:
wohl auch C++ wegen dem Overhead mit den Containern nicht gut brauchbar ist und erheblich schlechter als C abschneiden dürfte.
Kannst Du das mit dem Overhead der Container etwas ausführen?
-
Experte65 schrieb:
Mein Tipp:
[...]blabla[...]Sorry, aber im grossen und ganzen ist das bullshit. Ist nicht persönlich gemeint, einfach nur fakt.
-
@Threadersteller:
Java ist inzwischen bei vielen Dingen wirklich schnell, es gibt aber auch Aufgaben, in denen Java schnell mal um einen Faktor 10 langsamer als C++ ist. Das liegt aber nicht an einem "Runtime Overhead", sondern an anderen Aspekten der Sprache und ihrer Umsetzung.
Wenn man sich bewusst ist, an welchen Stellen die Sprache Schwachstellen bezüglich der Erzeugung performanten Codes hat, dann kann man damit definitiv auch relativ schnellen Code schreiben. Wenn man das nicht weiß, dann tappt man aber schnell in so eine Performancefalle und das Programm wird lahm.
Das betrifft übrigens nicht nur Java, sondern auch jede andere Sprache.
C++ hat auch derartige Performancefallen, in die man tappen kann. Aber dort ist es oft leichter, diese Fallen zu umgehen. Deshalb ist C++ Code weiterhin tendenziell schneller. Ich würde schätzen, im Schnitt um einen Faktor 1,5 oder so. Wenn dieser Faktor irrelevant ist, dann kann man ein Programm von diesem Gesichtspunkt her in beiden Sprachen schreiben. Es gibt aber auch Programme, die einfach so schnell wie möglich sein müssen.
-
Experte65 schrieb:
Mein Tipp:
Bei so rechen-intensiven Anwendungen wie Schach spielen Dinge wie kluges
Caching, 64-Bit-Bitboard Operationen u.ä. eine derart vordergründige Rolle,
dass Dein Java-Freund auch bei noch so exzellenter, objektorientierter
Programmierung gegen eine 'reine', nativ kompilierte C Engine (die auch
weitestgehend die selben Algorithmen implementieren müsste (um überhaupt
vergleichbar zu sein!)) keine Chance haben dürfte und idR nicht annähernd an
die üblichen Suchtiefen eines C/C++ Schachprogramms herankommen wird.
Allgemein vermute ich, dass bei so rechenintensiven Problemstellungen
wie Schach (aber-trillionen mögliche Folgestellungen schon nach wenigen
Zügen) wohl auch C++ wegen dem Overhead mit den Containern nicht gut brauchbar
ist und erheblich schlechter als C abschneiden dürfte.Der Punkt ist doch, dass der Mensch nur Dinge bis zu einer gewissen Komplexität sinnvoll verarbeiten kann. Und dann ist halt die Frage, an welcher Stelle man ein Programm komplex macht. High-Level-Sprachen ermöglichen es einem, von den Details zu abstrahieren und die Komplexität somit ins allgemeine Konzept seines Programms zu verlagern. Bei Low-Level-Sprachen hat man hingegen die Möglichkeit und auch die Notwendigkeit, sich um alle Details zu kümmern. Das heißt, dass man auf der Detailebene automatisch jede Menge Komplexität kriegt. Dann wird es aber problematischer, zusätzlich auch noch komplexe Konzepte umzusetzen.
Mit anderen Worten: Man sagt schnell "bei gleichen Algorithmen ist das C-Programm schneller". Aber in einer High-Level-Sprache hat man eben mehr Zeit, sich um den Algorithmus zu kümmern. Deswegen hat bei gleichem Aufwand tendenziell das Programm in der High-Level-Sprache den besseren Algorithmus.
-
Ich bevorzuge immer C++. Performance ist dabei aber eher ein untergeordnetes Argument.
C++ finde ich deswegen gut, da man dort auch auf einer sehr hohen Abstraktionsebene programmieren kann. In meiner Applikationslogik gibt es keine Speicherverwaltung oder irgendwelche trickreichen Optimierungen. Applikationslogik muss gut lesbar und robust sein. Beides wird von C++ optimal unterstüzt. Nebenbei kann man bei Bedarf auch Maschinennah programmieren.
Ich bin immer wieder begeistert, wie robuste und einfache APIs man in C++ formulieren kann.
Wenn es um Performance oder andere rein technische Aspekte geht, dann weiss ich, dass mit C++ alles möglich ist, was mit der Hardware möglich ist. Wenn ich eine Abstraktionsebene wie eine VM habe, ist höchstens das möglich, was abstrahiert ist. Daher gibt es mit C++ einfach keine Grenzen.
Der Nachteil ist eher, dass die Features doch so umfangreich sind, dass es sehr lange dauert, bis man es ausreichend beherrscht. Ich wünschte mir, es gäbe einfach mehr Programmierer mit professionellen C++ Kenntnissen.