Java ist schneller als C++!



  • Jester schrieb:

    rapso schrieb:

    Jester schrieb:

    Wie macht man eine wirklich tolle PGO, wenn man das Zielsystem nicht genau kennt? Ein JIT könnte auf den genauen Prozessor, dessen Cache-Größe und sogar auf das aktuell zur Verfügung stehende RAM hin optimieren. Vermutlich kriegt man das aber auch mit C++ hin, einfach 30-40 verschiedene Executables für unterschiedlichste Situationen liefern. 😉

    indem man genau wie bei java nicht das finale binary, sondern den compiler input mitliefert. Ist bei den meisten dingen unter bsd/*nux eh der fall.

    Wie lange dauert es, bis Dein aktuelles Projekt durch den Compiler gelaufen ist? Wie praktikabel wäre das?

    Das Kompilieren des Programms gehört zur Installation. Das kann man wohl kaum zur Laufzeit dazurechen. ⚠
    Außerdem kompiliert man das Programm nur EINMAL. Java Programme werden hingegen bei JEDEM Start neu JIT kompiliert. ⚠



  • ⚠ mit cobol wär das nich passiert ⚠



  • Jester schrieb:

    Wie macht man eine wirklich tolle PGO, wenn man das Zielsystem nicht genau kennt? Ein JIT könnte auf den genauen Prozessor, dessen Cache-Größe und sogar auf das aktuell zur Verfügung stehende RAM hin optimieren. Vermutlich kriegt man das aber auch mit C++ hin, einfach 30-40 verschiedene Executables für unterschiedlichste Situationen liefern. 😉

    Na, 30-40 Exes ist ja mal übertrieben. Seien wir ehrlich: eine solche filigrane Optimierung macht nur bei wenigen Spezialanwendungen Sinn. Oder meint ihr, das sich PGO bei OpenOffice lohnen würde (ich meine spürbar!)? Nein, sicherlich nicht. Solche Anwendungen kompiliert man heute mit den normalen Optimierungs-Flags. Ein 3D-Spiel z.B. kann man für nen Pentium 4 kompilieren lassen (wenns eh als Mind-Anforderung auf der Packung steht).

    So, wann liefere ich aber als Software-Anbieter eine super optimierter Variante aus? Dann wenn ich eine Anwedung habe, wo sich z.B. PGO bemerkbar macht. Und das sind erstens nur die wenigsten Anwendungen und zweitens lässt man sich solche Anwendungen eh mit nem Extra-Preis bezahlen. Nehmen wir mal so eine Oracle-DB-Server: der kostet nicht 50 EUR, sondern bei einer Konzernlizenz mit Full-Support mehrere tausend Euro. Wir haben bei uns teilweise Software im Konzern, die für 250.000 EUR eingekauft wurde. Ehm... ja, da kann der Software-Anbieter natürlich locker eine speziell für die Ziel-Hardware optimierte Executable und Libs ausliefern. Warum auch nicht? Denn die Hardware beim Kunden wechselt ja nicht alle 2 Monate. Bei uns laufen Server und Mainframes Jahre durch.

    Das bei Java der JIT immer wieder neu optimiert, wenn die JAR angestartet wird, ist Design-bedingt, aber kein Vorteil ggü. C++.

    Und es gibt ja auch schon heute Closed-Source-Software, wo der Anbieter eh mehrere EXEs für verschiedene Plattformen anbietet... siehe Codeforge-IDE. Die haben mind. 6 verschiedene Binaries im Angebot, je nach dem was der Kunde für eine Plattform hat.

    Bei Opensource ist dann eh alles anders, da kann der Kunde selber seine PGO einstellen, wenn es dafür keinen Anbieter gibt. Aber auch solche Aufgaben können Opensource-Dienstleister übernehmen, will man es nicht selbst machen.

    Und wie gesagt, PGO macht meiner Meinung bei Meinstream-Anwendungen keinen wirklich große Sinn. Und ist bei C++ in dem Bereich auch nicht nötig.



  • Die meisten meinen hier irgendwie, dass Java-Serverprogramme einfach mit C++ Desktopprogrammen verglichen werden können und versuchen dann Konzepte 1:1 von der einen Welt in die andere zu übertragen.



  • Jester schrieb:

    rapso schrieb:

    Jester schrieb:

    Wie macht man eine wirklich tolle PGO, wenn man das Zielsystem nicht genau kennt? Ein JIT könnte auf den genauen Prozessor, dessen Cache-Größe und sogar auf das aktuell zur Verfügung stehende RAM hin optimieren. Vermutlich kriegt man das aber auch mit C++ hin, einfach 30-40 verschiedene Executables für unterschiedlichste Situationen liefern. 😉

    indem man genau wie bei java nicht das finale binary, sondern den compiler input mitliefert. Ist bei den meisten dingen unter bsd/*nux eh der fall.

    Wie lange dauert es, bis Dein aktuelles Projekt durch den Compiler gelaufen ist? Wie praktikabel wäre das?

    wie praktikabel linux/bsd/etc. mit den source packeten ist? naja, afaik ist das der source weg die beliebteste verbreitungsmethode von software auf diesen systemen. sogar das ganze OS kann man sich als source ziehen, obwohl viele distributionen precompilierte binaries haben, aber wenn du dir z.b. gentoo ziehst, oder auf ps2 das linux installierst, bekommst du alles fuer dein system perfect zugeschnitten compiliert.
    Da die dinge als source vorliegen und nicht nur als bytecode, kannst du auch weit mehr optimieren.



  • Der Grund warum alle neueren Sprachen* einen JIT einsetzen liegt meines erachten darin, dass man eh eine Art Bytecode-Zwischen-Code braucht um alle heute üblichen Optimierungen zu unterstützen und man dadurch den JIT sozusagen ohne großen Aufwand dazu kriegt.

    Das reine C/C++-Übersetzungsmodel erlaubt nun einmal keine intermodularen Optimierungen. Inlinen besteht nicht nur daraus den Funktionskörper zu Copy & Pasten sondern auch aus dem Auswerten dadurch entstehender konstanter Ausdrücke und vor allem aus einer effektiven Registerverteilung in der entstehenden Funktions. Mit fertigem x86 Maschinen Code sind diese Optimierungen quasi unmöglich und arten meisten in einem Minidecompiler aus welcher in den Linker integriert wird.

    Wenn man nun allerdings den Code zuerst in Bytecode verwandelt dann sind solche intermodularen Optimierungen eigentlich kein Thema mehr. Der Compiler inlined gar nichts mehr und der "Linker" kümmert sich um sämtliche Optimierungen dieses Typs. Wenn der Bytecode weise gewählt wurde dann geht das sogar sehr flott.

    Ob man Bytecode produziert ist also nicht mehr die Frage. Es geht einzig darum ob man ihn in Maschinencode fertig kompiliert oder eine VM einsetzt. Hier entscheidet man sich dann meisten für die VM da diese doch ein paar nette Vorteile bietet wie zum Beispiel die Prozessorunabhängigkeit der Programme.

    Um ein C/C++ Programm auf dem Zielrechner erst während der Installation zu übersetzen braucht man alle verwendeten Headers in der richtigen Version (und alle dazugehörigen Source Dateien wenn man intermodulare Optimierungen erst nimmt). Auf nicht Programmierer-Rechnern ist das eine ziemlich starke Abhängigkeit. Bei *nix ist das dank Packetverwaltung noch im Bereich des machbaren. Bei Windows sehe ich aber schwarz.

    *Implementierungen für Korinthen-Hacker



  • COBOL-Fan schrieb:

    Das Kompilieren des Programms gehört zur Installation.

    was? also ne. das fehlte noch.
    🙂



  • rapso schrieb:

    wie praktikabel linux/bsd/etc. mit den source packeten ist?

    du hast wieder mal nix gelesen und haust nur blinde drauf, gell? Kannst Du bitte bitte mal aufhören davon auszugehen, dass ich irgendwie völlig beschränkt bin? Oder kompilierst Du tatsächlich die Anwendung vor jeder Benutzung, um sie auch auf die aktuelle Systemauslastung hin zu optimieren (z.B. größe vs. geschwindigkeit). wie ist das bei dir bei der arbeit, legt ihr auch die sourcen bei? wie praktikabel ist das?



  • Ich bin immer wieder überrascht, warum anscheinend implizit davon ausgegangen wird, dass C++ und JIT-Compilierung sich gegenseitig ausschließen.

    Ich sehe selber große Vorteile bei der JIT-Compilierung, was das linken von dynamischen Libraries angeht, das ermöglicht inlining und erleichtert imho auch den Export von Klassen. Mir gefällt die momentane Lösung vom VC++ nicht, man kann zum Beispiel keine Klasse exportieren, die Member hat, deren Typ nicht exportiert ist, auch wenn dieser Member gar nicht Teil der öffentlichen Schnittstelle ist. Dieses ganze Speicherlayout-Gefrickel kann mit JIT-compilierung wahrscheinlich wesentlich eleganter gelöst werden.

    Aber irgendwie wird immer C++ und JIT-Compilierung gegenüber gestellt, das finde ich leicht irritierend. 😕



  • Jester schrieb:

    rapso schrieb:

    wie praktikabel linux/bsd/etc. mit den source packeten ist?

    du hast wieder mal nix gelesen und haust nur blinde drauf, gell? Kannst Du bitte bitte mal aufhören davon auszugehen, dass ich irgendwie völlig beschränkt bin? Oder kompilierst Du tatsächlich die Anwendung vor jeder Benutzung, um sie auch auf die aktuelle Systemauslastung hin zu optimieren (z.B. größe vs. geschwindigkeit). wie ist das bei dir bei der arbeit, legt ihr auch die sourcen bei? wie praktikabel ist das?

    Diese Optimierungsmöglichkeiten halte ich für übertrieben theoretisch.



  • Optimizer schrieb:

    Jester schrieb:

    rapso schrieb:

    wie praktikabel linux/bsd/etc. mit den source packeten ist?

    du hast wieder mal nix gelesen und haust nur blinde drauf, gell? Kannst Du bitte bitte mal aufhören davon auszugehen, dass ich irgendwie völlig beschränkt bin? Oder kompilierst Du tatsächlich die Anwendung vor jeder Benutzung, um sie auch auf die aktuelle Systemauslastung hin zu optimieren (z.B. größe vs. geschwindigkeit). wie ist das bei dir bei der arbeit, legt ihr auch die sourcen bei? wie praktikabel ist das?

    Diese Optimierungsmöglichkeiten halte ich für übertrieben theoretisch.

    mag sein, aber das war ja nicht rapsos Argument.

    ah, hast du grad mal nen link zu so einem C++ JIT Compiler?



  • Jester schrieb:

    rapso schrieb:

    wie praktikabel linux/bsd/etc. mit den source packeten ist?

    du hast wieder mal nix gelesen und haust nur blinde drauf, gell?

    doch ich hab's gelesen (jedenfalls 4seiten zurueck) und hab gesagt dass sowas in der art gemacht wird. genau wie es JIT gibt die sowas machen beim ersten start, also vor dem start, dem system entsprechend neu bauen. manche JIT lassen einen profilelauf rennen und beim zweiten start wird dann die system angepasste version gebaut.

    Kannst Du bitte bitte mal aufhören davon auszugehen, dass ich irgendwie völlig beschränkt bin?

    sehr gerne.

    Oder kompilierst Du tatsächlich die Anwendung vor jeder Benutzung, um sie auch auf die aktuelle Systemauslastung hin zu optimieren (z.B. größe vs. geschwindigkeit).

    nein, das waere voellig "beschraenkt". die laufleistung haengt bei den allermeisten programmen von den daten ab, nicht so sehr von compilierflags. wenn ich photoshop neu compilieren wuerde, weil ich mir ein icon ansehen will, aber weil mein system gerade speichermaessig ausgelastet ist, ich alles neu bauen muss um es mir dann in 1.5 statt 1.6mb anzusehen, waere das recht sinnfrei.

    deswegen, erst profilen, dann optimieren, ergo: pgo. entsprechend gehoeren daten zum profilen und optimieren dazu.

    wie ist das bei dir bei der arbeit, legt ihr auch die sourcen bei? wie praktikabel ist das?

    wir haben builds fuer die gelaeufigsten systeme. diese bauen ueber nacht durch. alles in allem sind es ca 10 8-core server + ca 100 distributed clients die ca 3stunden bauen, wobei das production builds sind, die sind entsprechend nicht bis zum ende optimiert, da es noch keine finalen daten gibt.

    mit finalen daten benutzen wir halt pgo, und das fuer verschiedene systeme und verschiedene teile eines builds. du wuerdest es nicht glauben wieviele permutationen wir haben.

    aber wenn du es wissen willst, wie praktikabel es ist das optimale programm zu bauen, versuch gerne mal: http://www.coyotegulch.com/products/acovea/

    ich glaube dann kommt jeder zu dem schluss...



  • Was macht ihr mit den vielen Permutationen dann? Werden die tatsächlich alle ausgeliefert und für den Kunden die jeweils passendste gewählt, oder nehmt ihr die, die im Durchschnitt über die Systeme die beste Performance liefert?



  • Jester schrieb:

    ah, hast du grad mal nen link zu so einem C++ JIT Compiler?

    Du kannst zum Beispiel den VC++ Zwischencode erzeugen lassen (auch wenn du bei Standard C++ bleibst).



  • Echt, wie geht das denn? PGO weiß ich, wie's mit dem VC funktioniert, aber wo finde ich den Zwischencode? Oder meinst Du das via C++/CLI?



  • Ja, du musst aber nicht die Spracherweiterungen nutzen. Du kannst Standard C++ zu .Net Zwischencode compilieren, der Schalter dafür ist /clr:pure.
    Die Klassen sind dann natürlich nicht von anderen .Net-Sprachen aus nutzbar, sondern wie üblich nur von anderen VC++-Projekten aus. Du hast halt den Vorteil (oder Nachteil) der JIT-Compilierung. Die meisten Optimierungen werden auch auf den Zwischencode angewendet.



  • man kann zum Beispiel keine Klasse exportieren, die Member hat, deren Typ nicht exportiert ist, auch wenn dieser Member gar nicht Teil der öffentlichen Schnittstelle ist

    Klar geht das, man muss nur die dummen Warnings ignorieren die VC dann absetzt.
    Man kann das sogar machen WENN das Member Teil der öffentlichen Schnittstelle ist, bloss kann es dann sein dass man das Client Programm nichtmehr linken kann.



  • man muss nur die dummen Warnings ignorieren die VC dann absetzt.

    bloss kann es dann sein dass man das Client Programm nichtmehr linken kann

    Ich weiß nicht, ob du das verstehen kannst, aber das sind beides statements, die tiefstes Mistrauen in mir wecken?!



  • Jester schrieb:

    ah, hast du grad mal nen link zu so einem C++ JIT Compiler?

    http://llvm.org/
    Ist zwar glaub ich eher auf die Kompilierung des Bytecodes zu herkömmlichen Programmdateien ausgerichtet, allerdings gibt es auch JIT Compiler für die gängigsten Prozessoren. Das C/C++ Frontend ist ein angepasster GCC. Ich hab keine praktischen Erfahrungen in der Verwendung.



  • Optimizer schrieb:

    man muss nur die dummen Warnings ignorieren die VC dann absetzt.

    bloss kann es dann sein dass man das Client Programm nichtmehr linken kann

    Ich weiß nicht, ob du das verstehen kannst, aber das sind beides statements, die tiefstes Mistrauen in mir wecken?!

    Ich weiss nicht ob du das verstehen kannst, aber mir wäre es lieb wenn du erklären könntest WAS genau jetzt dein Misstrauen weckt.

    BTW: ich wollte nur feststellen dass deine Aussage "geht nicht" so einfach nicht stimmt. Ob man es machen mag ist jedermanns eigene Sache. Ich sehe es in vielen Fällen als unproblematisch an.


Anmelden zum Antworten