Hackerboard Wiki HaboBlog
Hackerboard bei Facebook Hackerboard bei Google+ Hackerboard bei Twitter

[HaBo]

 
Code Kitchen Allgemeines Coder-Forum rund um das Programmieren eigenständiger, ausführbarer Programme.

Bücher zum Thema C++ Laufzeit Optimierung

Diskussion: Bücher zum Thema C++ Laufzeit Optimierung im Forum Code Kitchen, in der Kategorie Software Home; Anzeige Hallo HaBo, ich suche nach Büchern die sich mit der Laufzeit-Optimierung von C++-Programmen beschäftigen. Konkret geht es darum, die ...

Like Tree2Likes
  • 2 Post By BieblSoft

Antwort
Alt 21.02.12, 17:07   #1 (permalink)
Member of Honour
 
Registriert seit: 02.10.01
Indi Leistung: Z3
Likes: 0
Standard Bücher zum Thema C++ Laufzeit Optimierung

Anzeige

Hallo HaBo,

ich suche nach Büchern die sich mit der Laufzeit-Optimierung von C++-Programmen beschäftigen.

Konkret geht es darum, die Laufzeit eines Programms, das unter Linux mit g++ kompiliert wird, best möglich zu verringern. Mir geht's nicht/weniger um spezielle Algorithmen, sondern um verschiedenste Aspekte, an die man bei "normalen" Programmen eher nicht denkt: zb. das Vermeiden von Rekursionen oder mehrdimensionalen Arrays, Programmstrukturen, Speicherzugriff/Adressierung oder ähnliche Aspekte.

Dh. ich möchte besser verstehen, was der Compiler bzw. der Prozessor aus meinem Code macht und wie ich unnötige Operationen vermeiden kann.

Nachteile einer solchen Vorgehensweise, wie mangelnde Lesbarkeit des Quellcodes, Portierungsprobleme usw. sind mir bewusst und auch relativ egal.

Weiters bin ich prinzipiell auch nicht abgeneigt, Assembler-Code direkt in meinen C++-Quellcode einzubauen. Allerdings erscheint mir das zum derzeitigen Zeitpunkt noch zu früh. Aber falls in diese Richtung jemand Tipps hat, das Programm läuft derzeit auf einem Intel Core i5 und wird auch langfristig gesehen nur auf Intel-Prozessoren zum Einsatz kommen.

Falls jemand ein paar Ansätze hat und interessante Bücher (englisch/deutsch) in diese Richtung kennt, bin ich für alle Hinweise dankbar.

lg

Indi ist offline   Mit Zitat antworten
Alt 21.02.12, 17:26   #2 (permalink)
Senior Member
 
Registriert seit: 13.07.08
enkore Leistung: K 6-3enkore Leistung: K 6-3enkore Leistung: K 6-3
Likes: 85
Standard

Probier erstmal ein paar Compiler aus, neben GCC lohnt sich idR ein Blick auf LLVM. Der kann einige Dinge nämlich um Welten besser optimieren als der GCC (prinzipbedingt).
Ansonsten ist das meiste nicht an die Sprache gebunden, da die Sprachfeatures (abgesehen von Späßen wie RTTI) von C++ eh compile-time sind und daher die Laufzeit kaum beeinflussen.

Grundlegende Ratschläge:
-bei großen Datenstrukturen, besonders mit vielen Entitäten (=> flyweights) entweder spezialisierte Strukturen nehmen (siehe Klammer vor dieser) oder direkt, ganz un-C++ig, direkt auf Speicher arbeiten, d.h. so wie du es in C machen würdest.
-RTTI vermeiden. S.o.
-Häufig aufgerufene Funktionen ("for x in große_liste: calculate(x)") möglichst in modulübergreifenden Dateien, also idR Headers auslagern, um Inlining zu ermöglichen*
-Effiziente Algorithmen verwenden, nicht die schönste/einfachste Datenstruktur nehmen und dann mit schlechten Algorithmen arbeiten, sondern möglichst schnell operierende Datenstrukturen verwenden. Binärbäume sind nicht wirklich schön oder elegant, aber wahnsinnig schnell zu durchsuchen

Wenn du das beachtest, kann man selbst mit großem Aufwand die Perfomance nur noch marginal steigern.

Weitere Schlagwörter: Lazy Evaluation, runtime optimization (wie es z.B. LLVM machen kann), Profiling - grundlegendes Werkzeug um nicht an den falschen Stellen Zeit mit Optimierungen zu verschwenden, ...

* So kann z.B. PyPy in einigen Fällen 2-4 mal schneller sein, als das gleiche Programm in C
__________________
"It is the human race! The deterioration of the spirit of man. Man undermining himself, causing a self-willed, self-imposed, self-evident self-destruction."
+++ BREAKING +++ Troll ertrinkt im Planschbecken +++
enkore ist offline   Mit Zitat antworten
   
HaBOT
 
- Anzeige -

Werbung ist gerade online    
Alt 21.02.12, 17:44   #3 (permalink)
 
Benutzerbild von Defcon_5
 
Registriert seit: 30.01.12
Defcon_5 Leistung: Facit NTK
Likes: 4
Standard

Hast Du Dir schon mal dieses Buch angesehen?: Linux-UNIX-Programmierung. Das umfassende Handbuch - Das Buch von Galileo Computing

Ich hatte mal damit angefangen, hab es dann aber vor einem Jahr wieder verkauft, da ich kein Linux mehr benutze. Ich fand das Buch gut, ob Du aber darin findest was Du speziell suchst weiß ich nicht; gibt eine neuere Auflage.
Defcon_5 ist offline   Mit Zitat antworten
Alt 21.02.12, 17:53   #4 (permalink)
CDW
Moderator
 
Benutzerbild von CDW
 
Registriert seit: 20.07.05
CDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: Opteron
Likes: 202
Standard

Von den Papers von Agner hatte ich einen guten Eindruck:
Software optimization resources. C++ and assembly. Windows, Linux, BSD, Mac OS X
Da gibt es jede Menge "high level" Möglichkeiten, die architekturbedingt z.B deutlich schneller laufen, aber nicht (immer) vom Compiler durchgeführt werden können[0].
Es sollte auch was von Intel geben (intel c++ compiler optimization), wobei das eher auf den Intelcompiler eingeht.

[0] Z.B Zugriffe auf mehrdimensionale Arrays:
Code:
for (x = 0, x < size, x++)
  for (y = 0, y < size2,y++)
    do_something_with: arr[y][x]
vs.
Code:
for (y = 0, y < size, y++)
  for (x = 0, x < size2,x++)
    do_something_with: arr[y][x]
Die erste Version dürfte deutlich langsamer sein (vor allem bei großen Arrays) - da die innere Schleife immer einen "Zeilensprung" macht und der Cache kaum zur Geltung kommt.
__________________
Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf!
Selig, wer nichts zu sagen hat und trotzdem schweigt.
CDW ist offline   Mit Zitat antworten
Alt 21.02.12, 18:46   #5 (permalink)
Senior Member
 
Benutzerbild von lookshe
 
Registriert seit: 10.03.07
lookshe Leistung: 8086
Likes: 19
Standard

Zitat:
Zitat von CDW Beitrag anzeigen
Die erste Version dürfte deutlich langsamer sein (vor allem bei großen Arrays) - da die innere Schleife immer einen "Zeilensprung" macht und der Cache kaum zur Geltung kommt.
Das dürfte aber kaum Auswirkung haben, da auch mehrdimensionale Arrays letztendlich als eindimensionale abgebildet werden und es somit beides nur eine einfache Pointerarithmetik ist.

Ansonsten wäre noch erwähnenswert, dass man sich mal den Zwischencode des Compilers anzeigen lässt. Dort sieht man oftmals schon einige Optimierungen, die die Compiler aus dem Code machen.

Und bei Schleifen ist noch wichtig, sofern diese eine feste Größe haben (also bspw. for (int i=0;i<4;i++)), dass sie aufgedrösselt werden, also der Inhalt der Schleife einfach 3 mal hingeschrieben wird. Das erspart die Initialisierung der Laufvariable, das Weiterzählen selbiger und letztendlich auch die Prüfung, ob die Endbedingung erreicht ist. Macht zum Beispiel Sinn, wenn man mit Vektoren und Matrizen fester Größe hantiert.
lookshe ist offline   Mit Zitat antworten
Alt 21.02.12, 19:25   #6 (permalink)
 
Benutzerbild von benediktibk
 
Registriert seit: 03.05.07
benediktibk Leistung: 8086benediktibk Leistung: 8086
Likes: 50
Standard

Ich habe Effektiv C++ programmieren von Scott Meyers gelesen und fand das Buch eigentlich recht gut. Nicht alle Dinge darin sind empfehlenswert, einfach nur stur die Ratschläge anwenden würde ich nicht empfehlen, aber wenn man es mit Hirn durchliest hilft es auf jeden Fall weiter.

mfg benediktibk
__________________
The essential prerequisite for building an expert system is to have an expert. - Frederick P. Brooks, Junior

Und wenn Ihr einen Politiker trefft der das gut findet - trefft ihn bitte ordentlich. - Chromatin
benediktibk ist offline   Mit Zitat antworten
Alt 21.02.12, 19:26   #7 (permalink)
Senior Member
 
Registriert seit: 13.07.08
enkore Leistung: K 6-3enkore Leistung: K 6-3enkore Leistung: K 6-3
Likes: 85
Standard

@lookshe:
Das machen Compiler ggf. automatisch. Es bringt fast nie etwas das von Hand zu machen...
__________________
"It is the human race! The deterioration of the spirit of man. Man undermining himself, causing a self-willed, self-imposed, self-evident self-destruction."
+++ BREAKING +++ Troll ertrinkt im Planschbecken +++
enkore ist offline   Mit Zitat antworten
Alt 21.02.12, 20:03   #8 (permalink)
CDW
Moderator
 
Benutzerbild von CDW
 
Registriert seit: 20.07.05
CDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: Opteron
Likes: 202
Standard

Zitat:
Zitat von lookshe Beitrag anzeigen
Das dürfte aber kaum Auswirkung haben, da auch mehrdimensionale Arrays letztendlich als eindimensionale abgebildet werden und es somit beides nur eine einfache Pointerarithmetik ist.
Sicher?

"arr[y][x]" sollte letzendlich in sowas wie
arr_addr + y*row_size + x aufgedröselt werden.
Angenommen wir arbeiten in einem 256 * 256 int Array.
in der ersten Schleife wird so zugegriffen:
1:addr + 0*1024 + 0
2:addr + 1*1024 + 0
3:addr + 2*1024 + 0
...

also in 1 KB Abstand
in der zweiten dagegen

1:addr + 0*1024
2:addr + 0*1024 + 4
Also 4 Byte Abstand.

Die Vor/Nachteile haben nichts mit der Abbildung auf 1 Dimension zu tun, sondern mit dem Abstand zwischen den Speicherzugriffen sowie "Cachelines"

Soweit ich mich entsinne, wird Cache in Blöcken gefüllt - d.h bei einem Cachemiss wird nicht nur 1 Byte nachgeladen, sondern direkt ein ausgerichteter Speicherblock (zumindest vom Prinzip - Details nachzuschlagen überlasse ich hier dem Leser *g* ).

Die zweite Variante dürfte also das Cachen deutlich besser ausnuzten (sofernt die Elementgröße < Cachelinegröße ist, oder so um den Drehe - vereinfacht gesagt nuten Caches die Lokalitätseigenschaften der Programmzugriffe aus - daher sollte man die Lokalität zumindest nicht absichtlich zerstören ).

PS:
"Pointerarithmetik" im Sinne von C/C++ ist optimierungstechnisch sehr problematisch.
Insbesondere bei Arrayzugriffen sollte man eher "natürlichen" Code wählen, anstatt selbstständig mit Pointer zu rechnen - Arrayzugriffe sind sehr häufig gebrauchte Muster und können dementsprechend gut erkannt und optimiert werden.

Edit:
beispiel   

Code:
#define SIZE 256*32
int a[SIZE][SIZE];
int main(void)
{
  int i, j, k = 0;
  for(j = 0; j < SIZE; j++)
		{
		for(i = 0; i < SIZE; i++)
			a[j][i] = i;
		} 
  int i, j, k = 0; 
/* Sequentieller Speicherzugriff */
	for(j = 0; j < SIZE; j++)
		{
		for(i = 0; i < SIZE; i++)
			k += a[j][i];
		}    
    return k;   
}
vs.
Code:
#define SIZE 256*32
int a[SIZE][SIZE];
int main(void)
{
   int i, j, k = 0;
  for(j = 0; j < SIZE; j++)
		{
		for(i = 0; i < SIZE; i++)
			a[j][i] = i;
		} 
  int i, j, k = 0;
/* nicht sequentieller Specherzugriff */
	for(i = 0; i < SIZE; i++)
		{
		for(j = 0; j < SIZE; j++)
			k += a[j][i];
		}    
    return k;   
}
hat bei gcc -O3 ca. 6-fachen Laufzeitunterschied.
__________________
Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf!
Selig, wer nichts zu sagen hat und trotzdem schweigt.
CDW ist offline   Mit Zitat antworten
Alt 21.02.12, 21:46   #9 (permalink)
 
Benutzerbild von Defcon_5
 
Registriert seit: 30.01.12
Defcon_5 Leistung: Facit NTK
Likes: 4
Standard

Das mehrdimensionale Felder linear gespeichert werden, daran kann ich mich auch noch erinnern; jedenfalls war es mal so:

Defcon_5 ist offline   Mit Zitat antworten
Alt 21.02.12, 22:07   #10 (permalink)
 
Benutzerbild von benediktibk
 
Registriert seit: 03.05.07
benediktibk Leistung: 8086benediktibk Leistung: 8086
Likes: 50
Standard

Legt ihr alle denn immer alles am Stack ab? Bei mir landen mehrdimensionale Arrays (z.B. Bitmaps) üblicherweise im Heap, und da liegen die Zeilen dann kreuz und quer im Speicher herum. Da ist es schon sinnvoll das per Hand zusammenzufassen in ein eindimensionales Array, wie soll das der Compiler denn auch automatisch machen.

Noch ein kleiner Tipp zum Optimieren: Zuerst herausfinden was wirklich lange dauert (Profiler oder einfach ein paar Zeitmessungen im Code) und erst dann optimieren anfangen. Da reicht es dann häufig eine oder zwei Funktionen zu optimieren weil eh 95% der Laufzeit dort draufgehen. Den Rest sollte man lieber so lassen wie er ist, da er dann höchst wahrscheinlich besser lesbar bleibt und eine Optimierung nicht wirklich merkbar wäre. Für den User bemerkbar sind Beschleunigungen um zum Beispiel den Faktor 2. Ob das Dingens aber 10% schneller ist wird dir als Benutzer nicht wirklich auffallen. Und so große Verbesserungen erreicht man üblicherweise nur durch einen besseren Algorithmus.
Ich will damit jetzt aber niemanden vom Optimieren abhalten, man sollte aber nur dann Optimieren, wenn es Sinn macht. Oft ist die bessere Wartbarkeit ein guter Grund die langsamere Variante zu wählen.

mfg benediktibk
__________________
The essential prerequisite for building an expert system is to have an expert. - Frederick P. Brooks, Junior

Und wenn Ihr einen Politiker trefft der das gut findet - trefft ihn bitte ordentlich. - Chromatin
benediktibk ist offline   Mit Zitat antworten
Alt 23.02.12, 10:15   #11 (permalink)
 
Registriert seit: 26.06.09
BieblSoft Leistung: 8086
Likes: 3
Standard C++ Code optimierung

Hallo,

zunächst mal möchte ich einigen der "Vorredner" in folgenden Punkten beipflichten:

1. "Vertraue moderner Compiler-Technologie"
Die Optimierungsmöglichkeiten des Compilers sind excellent und in vielen Fällen auch manuell nicht zu verbessern.
Selbst der Versuch, in Assembler oder C Laufzeitgewinne gegenüber optimiertem C++ Code zu erreichen, ist sinnlos, der optimierende Compiler ist allemal besser. Also @Indy: vergiss inline-Assembler !
Wer es nicht glaubt: Ich sende gerne Testcode zu

2. RTTI vermeiden
immer empfehlenswert, da es nur kostet und so gut wie nichts bringt. Einziger Verlust ist der dynamic_cast, aber es geht auch ohne den ganz gut.
In bestimmten Fällen Exception Handling ausschalten. Der verzicht bringt zusätzlichen Speicher und Geschwindigkeit, wenn man darauf verzichten kann.

3. Gute Algorithmen verwenden
Das gilt in erster Linie für die STL. Hier kann man aber sagen, dass die besten Algorithmen meist die sind, die der Container ohnehin bereitstellt, denn diese sind auf den jeweiligen Container optimiert.
Der häufigste Fehler ist der, den falschen Container zu benutzen oder den richtigen Container mit den falschen Methoden zu benutzen.

Zusätzlich möchte ich noch raten, bestimmte Code-Konstrukte zu vermeiden, wie z.B. den Bedingungsoperator. Einfach nur Mist, und fast immer schlechter als eine normale Fallunterscheidung. Lasst euch mal ein Assembler-Listing erzeugen und vergleicht mit normalem "if". Im besten Fall erzeugt der Bedingungsoperator identischen Code (z.B. bei gcc), im schlechtesten erheblich mehr Code (Microsoft, ohne Optimierungen)
Wieder: sende gerne Testcode zu, um zu beweisen, was ich behaupte

Virtualität wenn möglich vermeiden !
Virtual calls benötigen 10% mehr Laufzeit. Ebenso wird eine Menge zusätzlicher Speicher verbraten (VTable pro Klasse, pointer to vtable pro Objekt)

Templates verwenden ! Hier kann viel vom Compiler erledigt werden, was dann nicht zur Laufzeit ins Gewicht fällt.

Buchtip: "write great Code" von Randall Hyde, No starch press, 2 Bände.
Und alles von Scott Myers (hier aber darauf achten, die neuesten Auflagen zu nehmen, nur dort verwendet er massiv Templates.
throjan and Sleepprogger like this.

Geändert von BieblSoft (23.02.12 um 10:24 Uhr)
BieblSoft ist offline   Mit Zitat antworten
Alt 23.02.12, 19:44   #12 (permalink)
Member of Honour
Themenstarter
 
Registriert seit: 02.10.01
Indi Leistung: Z3
Likes: 0
Standard

Vielen Dank Leute für die zahlreichen und tollen Anregungen; insbesondere für den Link an CDW bzw. die Buchtipps an BieblSoft. Hatte nicht mit sovielen Antworten gerechnet.

Damit dürfte ich jetzt einige Zeit beschäftigt sein. Thx nochmal.
Indi ist offline   Mit Zitat antworten
Antwort
   
- Anzeige -

Werbung ist gerade online    

[HaBo] » Software Home » Code Kitchen » Bücher zum Thema C++ Laufzeit Optimierung
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind aus
Pingbacks sind aus
Refbacks sind aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Progamm Optimierung son-goku Code Kitchen 3 16.05.11 11:57
640x480 Optimierung webfreak (Web-) Design und webbasierte Sprachen 6 06.02.07 21:31
Kernel-Optimierung Nesssus Linux/UNIX 3 24.02.06 13:38
Bücher zum Thema hacken Zaireking Off topic-Zone 1 25.04.05 19:40
Bücher zum thema TCP/IP SeN Network · LAN, WAN, Firewalls 2 07.11.02 12:14


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61