Nutzt Compiler Optimierung!

-Nuke-

-Nuke-

Aktives Mitglied
Thread Starter
Dabei seit
13.09.2003
Beiträge
2.146
Reaktionspunkte
15
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:
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
 
Original geschrieben von Winn

Es gibt allerdings auch noch den gcc/g++ -O3 (maximale Optimierung) ;) Gruß Winn

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*
 
Original geschrieben von -Nuke-
-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.
&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
 
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
 
@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?
 
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 :)
 
Original geschrieben von 1904
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.

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.
 
Original geschrieben von -Nuke-
@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?
&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":

-fast

Optimize for maximum performance. "-fast" changes the overall
optimization strategy of GCC in order to produce the fastest possible
running code for PPC7450 and G5 architectures. By default, "-fast"
optimizes for G5. Programs optimized for G5 will not run on PPC7450. To
optimize for PPC7450, add "-mcpu=7450" on command line.

"-fast" currently enables the following optimization flags (for G5 and
PPC7450). These flags may change in the future. You cannot override
any of these options if you use "-fast" except by setting "-mcpu=7450".
Note that "-ffast-math", "-fstrict-aliasing" and "-malign-natural" are
unsafe in some situations. To build shared libraries with "-fast",
specify "-fPIC" on command line.

-O3
-funroll-loops
-fstrict-aliasing
-fsched-interblock
-falign-loops=16
-falign-jumps=16
-falign-functions=16
-falign-jumps-max-skip=15
-falign-loops-max-skip=15
-malign-natural
-ffast-math
-mdynamic-no-pic
-mpowerpc-gpopt
-force_cpusubtype_ALL
-fstrict-aliasing
-mtune=G5
-mcpu=G5
-mpowerpc64

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
 
Original geschrieben von -Nuke-
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.
&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 << i << 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 << i << 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 << i << 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
 
Zurück
Oben Unten