Nutzt Compiler Optimierung!

Dieses Thema im Forum "Mac OS X Entwickler, Programmierer" wurde erstellt von -Nuke-, 19.11.2003.

  1. -Nuke-

    -Nuke- Thread Starter MacUser Mitglied

    Beiträge:
    2.135
    Zustimmungen:
    15
    MacUser seit:
    13.09.2003
    Hi,

    mein Berufsschullehrer hat mich auf eine Idee gebracht. Er meinte in C++ dauern 3 verschachtelte "for"-Schleifen bis 65000 gezählt ein paar Jahre bis sie durchlaufen sind. Er hat uns das auch vorgerechnet.

    Naja. Ich habe es mal nach gemacht:

    #include <iostream>

    int main()
    {
    for(int i=0;i<=65000;i++)
    {
    for(int j=0;j<=65000;j++)
    {
    for(int x=0;x<=65000;x++)
    {

    };
    };
    std::cout << i << std::endl;
    };
    }

    OK! Compiliert mit folgendem Befehl:

    g++ -o Schleife Schleife.cpp

    Ein Durchlauf (bis zum "cout") dauert auf einem G4 mit 1,25Ghz rund 30 Sekunden.
    30*65000 = 1950000 Sekunden

    Das sind rund 22 Tage.

    OK! Compiliert mit folgendem Befehl:

    g++ -o Schleife Schleife.cpp -O2 -mcpu=7450 -mtune=7450 -maltivec -mabi=altivec -faltivec -pipe -fsigned-char -mpowerpc-gfxopt

    Der Durchlauf dauert jetzt nur noch 6 Sekunden!
    6*65000 = 390000

    Das sind rund 5 Tage.

    Interessant, oder? Optimierung vom Compiler kann schon sehr viel helfen. Sicher ist das Beispiel nicht gerade komplex, aber immerhin ein starker Geschwindigkeitszuwachs.

    Wie mein Lehrer auf "Jahre" kommt, kann ich mir nur so erklären das er das Ganze auf nem AthlonXP 1600+ mit nem "Borland C Builder 6"-Compiler getestet hat. Anders kann´s ja nicht sein. Er lobt das Ding ja immer in den Himmel. Naja! GCC scheint da ja fixer zu sein! *ggg*

    Na dann! Gute N8!
     
    Zuletzt bearbeitet: 19.11.2003
  2. Winn

    Winn MacUser Mitglied

    Beiträge:
    423
    Zustimmungen:
    0
    MacUser seit:
    07.11.2002
    Optimierung in C/C++ sind schon eigenständige Bücher wert...

    Du kannst Deine Schleifen noch zusätzlich verschnellern, wenn Du anstatt der Präfix (I++) Inkrementierung eine Postfix (++I)Inkrementierung einsetzt... das hat den Vorteil, das "ungeprüft" inkrementiert kann, der Compiler bzw. das Executable muß keine zusätzlichen "Check-Bremsen" einführen, sondern kann "stupide" weiterrechnen...

    Es gibt allerdings auch noch den gcc/g++ -O3 (maximale Optimierung) ;) Bessere Optimierungen erreicht man allerdings manchmal eher mit den kommerziellen Compilern, wie dem von Metroworks... kommt immer darauf an, ob es sich die GCC Community gefallen läßt, wenn wer schneller ist :D

    Gruß Winn
     
  3. -Nuke-

    -Nuke- Thread Starter MacUser Mitglied

    Beiträge:
    2.135
    Zustimmungen:
    15
    MacUser seit:
    13.09.2003
    Hi,

    -O3 bringt nix. Nur Probleme. Laut Gentoo ist´s auch instabil. Ansonsten bringt ++i auch nix. Ich glaube viel kann man da nicht Code-mäßig Optimieren.

    Ob Metroworks und etc. schneller sind glaube ich nicht. Borland und MS-Compiler sind ja auch eher langsam. Eher der IBM-Compiler auf´m G5, aber den hab ich nicht! *ggg*
     
  4. Winn

    Winn MacUser Mitglied

    Beiträge:
    423
    Zustimmungen:
    0
    MacUser seit:
    07.11.2002
    &nbsp;

    -O3 bringt schon was, ist aber nicht problemlos... bei Deinen einfachen Schleifenkonstruktionen allerdings sicher nicht zwingend, Schleifen scheinen schon in -O2 optimiert zu werden... in anderen Programmen gibt -O3 allerdings richtig Gas...

    Metroworks ist sehr wohl schneller... Motorola ist Mitbesitzer von Metroworks der für die Entwicklung des G4/G3 verantwortlich ist, d.h. Metroworks bekam die Architektur sehr viel besser zu Gesicht, als die Konkurrenz... ist die gleiche Geschichte, wie das der Intel Compiler schneller auf Intel Prozessoren ist, als die Konkurrenz... wenn auch nur ein Quentchen...

    Gruß Winn
     
  5. Descartes

    Descartes unregistriert

    Beiträge:
    189
    Zustimmungen:
    0
    MacUser seit:
    14.12.2002
    Wenn du gcc 3.3 hast (Panther + Xcode) dann probier mal folgendes:

    g++ -fast -mcpu=7450 -o Schleife Schleife.cpp

    oder wenn du einen G5 Rechner hast:

    g++ -fast -o Schleife Schleife.cpp

    Laut Apple Entwickler-Doku wird mit der Compiler-Option "-fast" bereits jede mögliche Optimierungsoption eingeschaltet die möglich ist und sinn macht. Allerdings erzeugt "-fast" per default Code für die 64bit "G5" CPU. Diese Programme sind auf G4 CPUs nicht ablauffähig. Daher muss für G4 Systeme noch zusätzlich mit der Compiler-Option "-mcpu=7450" dem Compiler mitgeteilt werden, 32bit G4 Code zu erzeugen. Die mit dieser Einstellung erzeugten Programme laufen dann sowohl auf G4 als auch unter G5 Rechner.

    Ansonsten kannst du dir auch den erzeugten Assembler Quellcode anschauen und anhand dessen überprüfen, wie lange dein Programm laufen wird. Hierfür packst du noch zusätzlich die Compiler-Option "-S" in den Compiler-Aufruf. Der Assembler Quellcode liegt dann in der Datei "Schleife.s":

    g++ -S -fast -mcpu=7450 Schleife.cpp

    oder wenn du einen G5 Rechner hast:

    g++ -S -fast Schleife.cpp
     
  6. -Nuke-

    -Nuke- Thread Starter MacUser Mitglied

    Beiträge:
    2.135
    Zustimmungen:
    15
    MacUser seit:
    13.09.2003
    @Descartes

    BOAH! Danke! 3 Sekunden.

    3 Sekunden. Das ist ja Wahnsinn. Mein Lehrer wird umfallen. Der hat ja schon geschluckt, als ich sagte 6 Sekunden pro durchlauf.

    Kann man sich irgendwo ansehen welche Schalter alle gesetzt werden bei -fast?
     
  7. 1904

    1904 MacUser Mitglied

    Beiträge:
    21
    Zustimmungen:
    0
    MacUser seit:
    21.11.2003
    Nabend! Das ist natuerlich klasse.

    (NUR) weil ich gerade an einem Intel-Rechner sitze, hab ich mir den naechst besten Compiler besorgt, die Compileroptionen auf "max optimize" gesetzt und laufen lassen. Der Sekundenzeiger an meinem Wecker kommt nicht bis 3 Sekunden pro Durchlauf.

    P4 2.5ghz

    An was fuer einem Mac laesst Du das Programm laufen?


    Nachtrag: Habs gefunden, in Deinem ersten Beitrag :)
     
  8. -Nuke-

    -Nuke- Thread Starter MacUser Mitglied

    Beiträge:
    2.135
    Zustimmungen:
    15
    MacUser seit:
    13.09.2003
    Hi,

    klar. Der Vergleich mit dem x86 bezog sich nur auf die feste Meinung des Lehrers. Ich weiß echt nicht wie er auf Jahre kommt. Er sagte etwas von 99 Jahren. Ich habe es mal mit 650000 gestetet. Ein Durchlauf dauert 3 Minuten und ungefähr 50 Sekunden. Das wären 4,7 Jahre. Immernoch deutlich unter seiner Zahl.

    Naja, wer weiß. Am Donnerstag teste ich es mal mit ihm. Schade das ich meinen Mac nicht mitnehmen kann. Ich könnte ja auch ein Video machen.

    Ich sehe gerade das das kleine Programm riesige 656 kb hat. Ziehmlich fett. Aber schnneeeeeeellllllll. *ggg*

    P.S. Ich denke mal wenn du einen Intel-Compiler nutzen würdest, würdest du bestimmt auf unter 2 Sekunden kommen. Weil soooo schnell kann ein G4 nun auch nicht sein. Weil seine Schwäche ist ja schon immer Integer gewesen, was Intels Stärke ist. Immerhin hat du das doppelte an Ghz. Ich hab zwar 2 CPUs drinnen, aber das Programm ist ja eh nicht Multiprozessor-fähig.
     
  9. Descartes

    Descartes unregistriert

    Beiträge:
    189
    Zustimmungen:
    0
    MacUser seit:
    14.12.2002
    &nbsp;
    Klar, lies mal die folgende Webseite:

    Using the GNU Compiler Collection (GCC) :: Options That Control Optimization
    http://developer.apple.com/documentation/DeveloperTools/gcc-3.3/gcc/Optimize-Options.html

    hier der wichtige Abschnitt zur Compiler Option "-fast":

    ansonsten sicher noch ganz nützlich sind folgende TNs:

    TN2086: Tuning for G5: A Practical Guide
    http://developer.apple.com/technotes/tn/tn2086.html

    TN2087: PowerPC G5 Performance Primer
    http://developer.apple.com/technotes/tn/tn2087.html
    enthält u.a. Do's und Don'ts den G5

    Weitere Dokumentation findet sich bei installierten Developer Tools
    unter file:///Developer/Documentation/Performance/Performance.html
     
  10. Descartes

    Descartes unregistriert

    Beiträge:
    189
    Zustimmungen:
    0
    MacUser seit:
    14.12.2002
    &nbsp;

    Annahme 1: ein kompletter Schleifendurchlauf dauert 1 Sekunde
    Annahme 2: std::cout Kommando steht in der dritten Schleifenebene

    komplette Laufzeit für das Programm inkl. Ausgabe auf der Konsole:

    65000**3 / (3600 * 24 * 365) = 8.708.301 Jahre

    PHP:
    include <iostream>

    int main()
    {
      for(
    int i=0;i<=65000;i++)
        {
          for(
    int j=0;j<=65000;j++)
            {
              for(
    int x=0;x<=65000;x++)
                {
                  
    std::cout << << std::endl;
                }
            }
        }
      return 
    0;
    }
    Annahme 1: ein kompletter Schleifendurchlauf dauert 1 Sekunde
    Annahme 2: std::cout Kommando steht in der zweiten Schleifenebene

    komplette Laufzeit für das Programm inkl. Ausgabe auf der Konsole:

    65000**2 / (3600 * 24 * 365) = 133 Jahre

    PHP:
    include <iostream>

    int main()
    {
      for(
    int i=0;i<=65000;i++)
        {
          for(
    int j=0;j<=65000;j++)
            {
              for(
    int x=0;x<=65000;x++)   // * Diese Schleife sollte vom Compiler
                
    {                         // * weg-optimiert werden koennen und
                
    }                         // * somit keine Laufzeit verursachen.
              
    std::cout << << std::endl;
            }
        }
      return 
    0;
    }
    Annahme 1: ein kompletter Schleifendurchlauf dauert 1 Sekunde
    Annahme 2: std::cout Kommando steht in der ersten Schleifenebene

    komplette Laufzeit für das Programm inkl. Ausgabe auf der Konsole:

    65000 / 3600 = 18 Stunden 3 Minuten 20 Sekunden

    PHP:
    include <iostream>

    int main()
    {
      for(
    int i=0;i<=65000;i++)
        {
          for(
    int j=0;j<=65000;j++)       // * Diese Schleifen sollten
            
    {                             // * vom Compiler selbst
              
    for(int x=0;x<=65000;x++)   // * weg-optimiert werden
                
    {                         // * koennen und somit keine
                
    }                         // * Laufzeit verursachen.
            
    }                             // *
          
    std::cout << << std::endl;
        } 
      return 
    0;
    }
    Zum Vergleich:
    Der "Big-Mac" Cluster der Virginia-Tech Uni schafft etwa 11 TeraFLOPs pro Sekunde.
    Der Virgina-Tech Cluster wäre somit für die tiefste Verschachtelung noch immer gute 25 Sekunden beschäftigt. Allerdings nur, wenn man dieses Programm auch schön über die 1200 Rechner des Clusters verteilen könnte -- was man aber in diesem simplen Programm leider eben nicht kann.

    65**3 GigaOPs = 274,625 TeraOps =~ 25 Sekunden
    65**2 MegaOPs = 4,225 TeraOps =~ 0,3 Sekunden
     
Die Seite wird geladen...