Der Vorteil des Kompilierens auf der eigenen Maschine

  • Für alle, die glauben, daß ein Programm in Binärform immer gut und schnell läuft, sei einmal folgendes Beispiel des Performance-Vorteils, der durch das Kompilieren auf der eigenen Maschine entsteht, aufgezeigt. Der Vorteil dieser Optimierung ist teilweise sehr gravierend, da der Compiler den für die eigene Maschine am schnellsten ausführbaren Binärcode erzeugt.
    Ich habe dazu ein wirklich kleines und einfaches Programm in C geschrieben, daß im Prinzip nur aus einer For-Schleife besteht, die 100.000 Mal "Hallo Welt" ausgibt und die für die For-Schleife benötigte Zeit misst. Die genutzte IDE ist Code::Blocks 8.02, der Compiler dazu ist der GCC.
    Einmal habe ich den Code auf meiner Voodoo-Kiste (siehe Sig) übersetzt und einmal auf meinem aktuellen System mit Athlon64 X2 4200+ @ 2500 MHz, beide Male im Debug-Modus, also ohne jegliche Optimierung. Beide Programme liefen anschließend auf meinem Athlon64 X2.

    Das hier ist der Code des "Programms":

    Folgendes Ergebnis eröffnete sich mir:

    Code kompiliert auf AMD Athlon Thunderbird 900 MHz, Windows XP, Debugmodus (keine Optimierungen), ausgeführt auf Athlon 64 X2 4200+ @ 2500 MHz
    [Blockierte Grafik: http://www.abload.de/img/athlon91go.png]

    Code kompiliert auf AMD Athlon64 X2 4200+ @ 2500 MHz, Windows XP, Debugmodus (keine Optimierungen), ausgeführt auf Athlon 64 X2 4200+ @ 2500 MHz
    [Blockierte Grafik: http://www.abload.de/img/athlon64x2h2nq.png]

    Man sieht also, daß der für die eigene Maschine generierte Binärcode ~14 mal schneller ist, als der fremde Binärcode. Umgedreht ergibt sich ein ähnliches Ergebnis auf meiner Voodoo-Kiste.

    Ein ähnliches Ergebnis habe ich auch schon beobachtet, wenn man den Code auf einem Athlon XP 2600+ ausführt. Die Unterschiede sind zwar nicht so extrem wie in diesem Beispiel, aber deutlich zu bemerken.
    Auf meinem Voodoo-System schaffe ich es auf eine Laufzeit von unter 20 Sekunden (~19,2s, Shot reiche ich eventuell noch nach), auf meinem alten Hauptsystem mit dem Athlon XP 2600+ schaffte ich es NICHT unter 23 Sekunden, obwohl das System deutlich schneller war, als meine Voodoo-Kiste.

    Dieses Programm lässt sich übrigens besonders dafür misbrauchen, den Geschwindigkeitszuwachs, der durch das Übertakten entsteht, anzuzeigen und zu messen. Es reagiert auch auf Timing-Änderungen des RAM's. Ein Single-Core-Prozessor wird zu 100% ausgelastet und stürzt bei der Ausführung des Programms normal nicht ab, wenn er durch Übertakten instabil ist, das Programm stockt dann lediglich (zumindest bei meinen Experimenten) und die benötigte Zeit zum Ausführen wird mehr.

    Daraus folgt: Wenn man z.B. den Grafiktreiber der Voodoo's eigens auf dem eigenem System kompiliert, ist die Chance SEHR HOCH, deutlich BESSERE Performance aus seiner Voodoo herauszuholen. Man muß den Code aber leider so anpassen, damit man ihn auch mit einem modernen Compiler übersetzen kann.

    EDIT: Ich sollte nicht so große Postings machen, denn da entstehen viele Fehler :topmodel:

    "Du bist und bleibst a Mensch und du kannst eben net deine menschlichkeit überwinden."

    Dennis_50300

    17 Mal editiert, zuletzt von CryptonNite (27. Februar 2009 um 00:03)

  • oder den entsprechenen Compiler runterladen...
    Guter Test und Danke für den tipp
    musste mal sfft drauf ansprechen
    Wenn ich das richtig sehe müsste dann die v5 ca 5-15% schneller sein oder?
    (und die v5 6k zieht eine gf4ti ab)

    Prost,
    Bier

  • Theoretisch schon, da ein Grafiktreiber am Ende auch nur auf der CPU abläuft, damit die CPU weis, wie sie die Grafikkarte ansprechen soll und was die Grafikkarte überhaupt kann.
    Je schneller der Treiber auf der CPU läuft, desto schneller wird die Graka mit Anweisungen und Daten gefüttert und umso effizienter kann die Graka arbeiten und ist somit auch schneller.
    Besonders bei 3Dfx würde man das bei Win9x/ME-Systemen spüren, denn diese Treiber für V3/4/5 haben diese 2 T&L-Emulationen (Referenz und optimierte Emulation), die dadurch auch schneller sein würden.

    "Du bist und bleibst a Mensch und du kannst eben net deine menschlichkeit überwinden."

    Dennis_50300

  • Ich hab zwar auch schon viel Code gebaut (oder eher: Dem Build System / Compiler gesagt, er soll tun, ohne selbst viel Hand anzulegen), aber eines möchte ich gerne wissen!

    Ich es nicht möglich, Code für unterschiedliche Zielarchitekturen und CPU Features zu bauen (sodaß der Code einfach die CPU und ihre Feature Flags entsprechend detektiert, und nutzt, wenn vorhanden?)? Also sagen wir, ich baue ein Binary mit SSE2 Support, optimiert für eine P4 Pipeline. Aber ich baue auch einen Codepfad mit rein, der sauber und schnell auf Athlon64 CPUs rennt? Geht das nicht? Ein Binary, das auf mehrere Architekturen gleichzeitig optimiert ist..

    1-6000-banner-88x31-jpg

    Stolzer Besitzer eines 3dfx Voodoo5 6000 AGP Prototypen:

    • 3dfx Voodoo5 6000 AGP HiNT Rev.A-3700

    [//wp.xin.at] - No RISC, no fun!

    QotY: Girls Love, BEST Love; 2018 - Lo and behold, for it is the third Coming; The third great Year of Yuri, citric as it may be! Edit: 2019 wasn't too bad either... Edit: 2020... holy crap, we're on a roll here~♡!

    Quote Bier.jpg@IRC 2020: "Je schlimmer der Fetisch, desto besser!"

  • Ich hab zwar auch schon viel Code gebaut (oder eher: Dem Build System / Compiler gesagt, er soll tun, ohne selbst viel Hand anzulegen), aber eines möchte ich gerne wissen!

    Ich es nicht möglich, Code für unterschiedliche Zielarchitekturen und CPU Features zu bauen (sodaß der Code einfach die CPU und ihre Feature Flags entsprechend detektiert, und nutzt, wenn vorhanden?)? Also sagen wir, ich baue ein Binary mit SSE2 Support, optimiert für eine P4 Pipeline. Aber ich baue auch einen Codepfad mit rein, der sauber und schnell auf Athlon64 CPUs rennt? Geht das nicht? Ein Binary, das auf mehrere Architekturen gleichzeitig optimiert ist..

    Also, wenn ich dich richtig verstehe, fragst du, ob man z.B. X86 und X86_64 in einer Binary mischen kann. Das geht nicht, oder ist mir nicht bekannt. Der Binärcode ist zu unterschiedlich. Das merkt man z.B. schon an unterschiedlichen Varianten von Assembler, da gibts sogar Unterschiede zwischen Linux und Windows X86-Assembler.
    Ein Programm, daß für X86 in Assembler geschrieben ist, sieht z.B. ganz anders aus, als das selbe Programm mit der selben Funktion für PPC in Assembler.
    Unterstützt der Compiler allerdings die Architektur, z.B. X86_64, dann kann man dem Compiler beim Übersetzen mitteilen, daß er dafür optimieren und kompilieren soll. Man sollte die Sourcen aber auch an die architekturspezifischen Limitierungen (z.B. maximale Größe einer Variable) anpassen.

    Man kann aber natürlich Unterstützung für Extensions wie MMX, SSE oder 3DNow! natürlich in eine Binary einkompilieren, die dann aktiv wird, falls die CPU diese unterstützt.
    Allerdings MUSS man dann eine Funktion schreiben, die dies auch vorher ausliest, sonst hat man am Ende z.B. eine Binary, die auf nen Athlon einwandfrei läuft, aber auf nem Pentium ständig abstürzt, weil der Pentium kein 3DNow! unterstützt.
    Aber hin oder her, der Compiler optimiert immer auf die laufende Maschine, mit Ausnahme von Cross-Compilern.
    Darum hatte man auch früher Programme ausschließlich im Quellcode verkauft, getauscht und weitergegeben. Eingefleischte Linuxer, so wie ich ( :] ), bauen unter anderem aus gerade diesem Grund ihr Linux selbst aus den Quellen auf. Es ist zwar harte Arbeit und langwierig, aber die Geschwindigkeit entschädigt am Ende.

    "Du bist und bleibst a Mensch und du kannst eben net deine menschlichkeit überwinden."

    Dennis_50300

    2 Mal editiert, zuletzt von CryptonNite (25. Februar 2009 um 22:13)

  • Ok, x86 und x86_64 (oder x86 und PPC) mischen hatte ich eh nicht gemeint, sondern das Mischen von Optimierungen innerhalb der selben Architekturfamilie. Weil der AthlonXP und Pentium4 wären ja beide x86_32, trotzdem kann man ja angeblich einiges beim Kompilieren für die Netburst Pipeline optimieren. Die Frage wäre dann, ob der Binärcode sowohl am P4 als auch am AXP "optimalst" laufen kann, und falls ja, ob das Binary dadurch signifikant größer wird..

    Ich kenns nur vom Gentoo Linux (Source Distro), da kann man in den Use Flags für sehr viele Pakete Pentium4 Optimierungen oder halt auch so Sachen wie SSE2 aktivieren, wenn man Portage sagt, was es saugen und bauen soll...

    Wenn ich zum Beispiel eine leistungskritische Anwendung habe, wäre es halt fein, wenn die auf einem AthlonXP, Athlon64, Pentium4 und Core2 mit maximaler Optimierung läuft, ohne daß ich dazu jedes Mal neu bauen muß. :)

    1-6000-banner-88x31-jpg

    Stolzer Besitzer eines 3dfx Voodoo5 6000 AGP Prototypen:

    • 3dfx Voodoo5 6000 AGP HiNT Rev.A-3700

    [//wp.xin.at] - No RISC, no fun!

    QotY: Girls Love, BEST Love; 2018 - Lo and behold, for it is the third Coming; The third great Year of Yuri, citric as it may be! Edit: 2019 wasn't too bad either... Edit: 2020... holy crap, we're on a roll here~♡!

    Quote Bier.jpg@IRC 2020: "Je schlimmer der Fetisch, desto besser!"

  • Eine Optimierung auf nem P4 für nen Athlon XP ist nicht möglich, da die Funktionsweise der Prozessoren unterschiedlich ist. Sie sind zwar beide x86, aber sie sind technisch völlig unterschiedlich aufgebaut, daher kann ein Compiler auf nem P4 nicht auf einen Athlon XP optimieren.

    Wenn du Sourcen auf nem P4 kompilierst, dann sind die eben auf deinen P4 zugeschnitten und optimiert, weil der Compiler für eben diesen P4 den schnellsten Binärcode erzeugen muß.

    Man kann allerdings auch dem Compiler sagen, daß er den Code auf Speed optimieren soll (geht z.B. beim GCC), was auch auf fremden Prozessoren etwas bringt. Allerdings ist der entstehende Binärcode auch nur auf dem Rechner am schnellsten, auf dem er erzeugt wurde.

    Wenn du maximale Geschwindigkeit für ein Programm auf deinem Rechner haben willst, kommst du aber NIEMALS um das Kompilieren herum.
    Mit Optimierungen kannst du zwar auch Speed erreichen, aber selbst kompiliert ist immer schneller.

    Ob die Binary aber sich großartig in der Größe ändern würde, weis ich aber auch nicht. Ich denke aber, daß sich die Größe unterscheiden wird, denn es müsste ja einmal für den P4 und einmal für den AthlonXP optimierter Binärcode eingearbeitet werden.

    "Du bist und bleibst a Mensch und du kannst eben net deine menschlichkeit überwinden."

    Dennis_50300

  • Mal ne ganz blöde Frage ;) :
    Warum Kompilieren sich Treiber nicht "einfach" bei der Treiberinstallation?

    Ganz einfach:
    Am Aufbau eines Treibers kann man die Funktionsweise der Hardware oder einzelner Techniken erkennen.
    Da man in einem ständigen Konkurrenzkampf arbeitet, sind die Sourcen geschlossen, denn man will ja nicht, daß die Konkurrenz diese Technik ohne Weiteres nachbaut.
    Die Linux-Treiber für ATi (igitt, die sind noch schlechter, als die Treiber für Windows) und nVidia ( :) ) beinhalten aber auch Treiber-Sourcen, z.B. für das Control Panel und das Kernelmodul. Unter Linux ist das auch egal, denn Linux hat nur OpenGL (oder auch Glide) als Schnittstelle zur 3D-Hardwarebeschleunigung und die Spezifikation zu OpenGL ist für jeden auf http://www.opengl.org einsehbar, wobei Closed-Source Treiber unter Linux ne Grauzone ist. Auf alle Fälle gilt dann der Kernel als "tainted", beschmutzt.

    "Du bist und bleibst a Mensch und du kannst eben net deine menschlichkeit überwinden."

    Dennis_50300

    Einmal editiert, zuletzt von CryptonNite (26. Februar 2009 um 11:38)

  • Ja, oder die Treiber im Quelltext veröffentlichen, wenn man maximalen Speed haben möchte.

    "Du bist und bleibst a Mensch und du kannst eben net deine menschlichkeit überwinden."

    Dennis_50300

  • Auf meinem i7 mit nur einem core: Zeit: 0.090 Sekunden

    Und das mit dem Treiber auf P4 anpassen wenn man auf nem P4 kompiliert stimmt so nicht ganz. Du kannst dem compiler sagen fuer welche Platform gebaut werden soll. Nimmst du i386 laeuft dein Program auf ziemlich jeder x86 CPU.

    Einmal editiert, zuletzt von Harrold (12. März 2009 um 20:31)

  • Auf meinem i7 mit nur einem core: Zeit: 0.090 Sekunden

    Und das mit dem Treiber auf P4 anpassen wenn man auf nem P4 kompiliert stimmt so nicht ganz. Du kannst dem compiler sagen fuer welche Platform gebaut werden soll. Nimmst du i386 laeuft dein Program auf ziemlich jeder x86 CPU.

    Ja, aber es läuft auf deiner CPU am schnellsten. :P

    Übrigens:

    Meine alte Voodoo-Kiste braucht bei 1180 MHz nur 18,6s :spitze:

    [Blockierte Grafik: http://www.abload.de/img/1180lss8.png]

    [Blockierte Grafik: http://www.abload.de/img/athlon90011804rwv.png]

    Völlig krank :topmodel::spitze:

    "Du bist und bleibst a Mensch und du kannst eben net deine menschlichkeit überwinden."

    Dennis_50300

    3 Mal editiert, zuletzt von CryptonNite (12. März 2009 um 21:05)

  • Nicht nur deswegen, die meisten Consolen ham auch ne PPC architektur, welche auch etwas staerker ist als x86, soweit ich da nicht falsch liege. Ausserdem sind die Hardwarekomponenten viel naeher beieinander und braucht somit weniger Zeit um bits hin- und herzuschieben. Ausserdem muss speziell auf die Konsole programmiert werden, was ein optimieren schwer macht, aber dafuer auch viel Effektiver.

  • Irgendwas mache ich falsch...habe die Codes mit DevCpp kompiliert und ausgeführt...ich komme auf ca 23-25s. :wacko:

    Mein System...bitte nicht lachen:

    Phenom 9550 (4x 2.2ghz)
    4Gb Ram

    Wie sage ich dem Compiler, dass der für mein System entsprechend compilieren soll...bzw. Treiber im Quelltext veröffentlichen.

    Danke für Tipps und Tricks!

    Liebe Grüße

    Liebe Grüße, 3dfxbaron

    Was hat ein Informatiker in einem Gartenmarkt zu suchen ?
    Er sucht Binärbäume... :topmodel:

    Es gibt 10 verschiedene Menschen auf der Welt, die die Binär denken und die nicht!

  • Der Compiler kompiliert im Normalfall automatisch für dein System.

    Ich kenne DevCpp nur vom Namen her, habe damit nie gearbeitet. Möglicherweise hast du es falsch eingestellt?
    DevCpp wird doch nicht mehr weiterentwickelt, nicht war?
    Ich nutze als IDE Code::Blocks 8.02 (https://www.voodooalert.de/www.codeblocks.org). Das ist zwar Englisch (es soll aber einen Source-Patch für Deutsch geben), aber es funzt auch nativ unter Linux (und unter Win98, durch KernelEx). Somit hab ich unter beiden Systemen immer die gleiche IDE und brauch mich nicht jedes Mal umzustellen.

    "Du bist und bleibst a Mensch und du kannst eben net deine menschlichkeit überwinden."

    Dennis_50300

    3 Mal editiert, zuletzt von CryptonNite (14. März 2009 um 16:12)

  • Habe IDE Code::Blocks runtergeladen und nochmal compiliert...komme trotzdem immernoch auf diesselbe Ergebnis (23,7s).

    Laut Taskmanager liegt die Auslastung durchschnittlich auf 30%... :huh:
    Irgendwie müsste das Programm direkt im Register laufen...habe mit " register int i; " versucht, scheint aber nicht geholfen zu haben.

    Hast du das Programm auch einfach so installiert ohne hinterher etwas einstellen zu müssen?

    Liebe Grüße, 3dfxbaron

    Was hat ein Informatiker in einem Gartenmarkt zu suchen ?
    Er sucht Binärbäume... :topmodel:

    Es gibt 10 verschiedene Menschen auf der Welt, die die Binär denken und die nicht!

  • Einfach voll installieren, neues Projekt erstellen, Code einfügen, Build --> Build (oder Strg + F9).
    Ne registrierte Variable ist nicht nötig (bringt laut Dennis M. Ritchie (dem Schöpfer von C) auch nicht wirklich was, bzw. nur auf seeeehr langsamen Maschinen)

    Nutzt du Vista? Wenn ja, 64Bit???
    Ansonsten: Hast du C'n'Q an? Wenn ja, dann ists klar... Der Prozessor läuft auf Minimum.

    An dem Programm kann man nicht viel optimieren, dafür ist es ganz einfach zu simpel.

    "Du bist und bleibst a Mensch und du kannst eben net deine menschlichkeit überwinden."

    Dennis_50300

    5 Mal editiert, zuletzt von CryptonNite (14. März 2009 um 17:27)