Geschwindigkeitsoptimierung

Liebe Experten,

ich schreibe mit VC++ 6.0 ein Programm, das Videodaten verarbeitet, und es kommt natürlich auf möglichst effektive Programmierung an. Es kann eigentlich gar nicht schnell genug ablaufen. Nun mache ich Testdurchläufe und messe die Zeit zwischen Beginn und Ende des Vorgangs (dazu verwende ich die Funktion timeGetTime()).

Mir fällt auf, daß die Ablaufgeschwindigkeit z. B. durch eine andere Anordnung der Funktionen im Quelltext (der durchlaufene Code in den Funktionen bleibt aber derselbe) sich in für mich unvorhersehbarer Weise ändert. Ich habe z. B. einige zusammengehörende Funktionen der Übersichtlichkeit in eine neue zusätzlich Quelltextdatei getan. Das Programm tut genau dasselbe, aber um ca. 2 Prozent langsamer. Als ich davor mit einigen anderen Funktionen dasselbe machte, wurde das Programm geringfügig schneller.

Warum ist das so und welche (eventuell VC++ - typische) Tricks gibt es, die man zur Optimierung nehmen kann? Natürlich achte ich auf möglichst effektive Programmierung einzelner Algorithmen, z. T. mit Assembler/MMX. Mir fiel auch auf, daß mein Programm unter WinXP merklich schneller läuft als unter Win2000.

Grüße,

I.

Mahzeit I.

ich schreibe mit VC++ 6.0 ein Programm, das Videodaten
verarbeitet, und es kommt natürlich auf möglichst effektive
Programmierung an. Es kann eigentlich gar nicht schnell genug
ablaufen. Nun mache ich Testdurchläufe und messe die Zeit
zwischen Beginn und Ende des Vorgangs (dazu verwende ich die
Funktion timeGetTime()).

Kann man so machen, ist im Fall von Multimediaanwendungen aber nicht
optimal. Es nützt überhaupt nichts z.B. den Videodecoder bis zum
erbrechen zu optimieren und wenn dann das gesamte Packet zusammmen
kommt dann sorgt möglicherweise der Audiodecoder für ständige Page
faults im Video part.
Wirklich sinnvolle Aussagen erhält man nur, wenn man das gesamte
system (Anwendung) laufen läßt und dann die Idle-Time der CPU mißt.

Mir fällt auf, daß die Ablaufgeschwindigkeit z. B. durch eine
andere Anordnung der Funktionen im Quelltext (der durchlaufene
Code in den Funktionen bleibt aber derselbe) sich in für mich
unvorhersehbarer Weise ändert. Ich habe z. B. einige
zusammengehörende Funktionen der Übersichtlichkeit in eine
neue zusätzlich Quelltextdatei getan. Das Programm tut genau
dasselbe, aber um ca. 2 Prozent langsamer. Als ich davor mit
einigen anderen Funktionen dasselbe machte, wurde das Programm
geringfügig schneller.

Das hängt mit der Cache benutzung, alignment, prefetch queue, branch
prediction, etc zusammen. Durch verschieben von Codeteilen ändern
sich einige oder alle dieser Eigenschaften. Eine einzige Zeile
zusätzlichen Code kann dann allerdings wieder das Ergebnis umkehren.

Warum ist das so und welche (eventuell VC++ - typische) Tricks
gibt es, die man zur Optimierung nehmen kann? Natürlich achte
ich auf möglichst effektive Programmierung einzelner
Algorithmen, z. T. mit Assembler/MMX. Mir fiel auch auf, daß
mein Programm unter WinXP merklich schneller läuft als unter
Win2000.

Du bewegst dich da in Bereichen in denen ein Optimieren normalerweise
nicht mehr sinnvoll ist. Der Aufwand steht in keinem Verhältnis zum
Ergebnis. Wenn du allein Rücksicht auf Prefetch Queue und Cache
nehmen willst, müsste dein Programm erstmal hereausfinden auf
welcher CPU es läuft und dann in den Codepfad verzeigen der extra
für diese CPU, dieses CPU stepping und Cachegröße optimal ist.
Unterschiede Intel/AMD mal ganz außen vor…

Wenn du allerdings verstehen möchtest was da abgeht, kann ich dir
nur VTune von Intel empfehlen, dies ist ein Profiler Tool, welches
recht ordentlich darstellt warum eine CPU wieviel Zeit wo
verschwendet.

Gruß
Stefan

Hallo Stefan,

danke für den Vtune-Tip, ich habe gerade eine Test-CD angefordert.

Ich möchte nicht soweit gehen, das Programm dadurch zu optimieren, indem ich die speziellen Eigenschaften der Prozessor-Typen berücksichtige und entsprechend verzweige. Das wäre mir denn doch zu aufwendig.

Aber wenn mit einfachen Tricks ein paar Prozent Geschwindigkeitszuwachs noch herausgehen, dann würde sich das auf jeden Fall noch lohnen.

Konkret lasse ich eine kurze AVI-Sequenz (mit DV-Kamera aufgenommen) decodieren und in MPEG-1 codieren (nur Video) und vergleiche mit dem TMPGenc 2.5, und letzterer ist noch ein bißchen (vielleicht 20 - 30 %) schneller, bei gleichen Einstellungen.

Grüße,

I.

Hallo I.

danke für den Vtune-Tip, ich habe gerade eine Test-CD
angefordert.

Gern geschehen.

Ich möchte nicht soweit gehen, das Programm dadurch zu
optimieren, indem ich die speziellen Eigenschaften der
Prozessor-Typen berücksichtige und entsprechend verzweige. Das
wäre mir denn doch zu aufwendig.

Das macht auch in 99,99% aller Fälle keinen Sinn.

Aber wenn mit einfachen Tricks ein paar Prozent
Geschwindigkeitszuwachs noch herausgehen, dann würde sich das
auf jeden Fall noch lohnen.

Wenn man (mit ein bischen Übung) konsequent Code schreibt der
vom Compiler einfach verstanden wird und ständig darum bemüht ist
optimale Performance zu liefern, dann findet man „so“ nicht mehr viel
an Prozenten.
Das ist dann zwar nicht optimal lesbar und wartbar aber schnell.
C++ verbietet sich dann leider auch von selbst, für Oberflächen OK,
alles was innen ist bleibt reines C.

Konkret lasse ich eine kurze AVI-Sequenz (mit DV-Kamera
aufgenommen) decodieren und in MPEG-1 codieren (nur Video) und
vergleiche mit dem TMPGenc 2.5, und letzterer ist noch ein
bißchen (vielleicht 20 - 30 %) schneller, bei gleichen
Einstellungen.

Das hat Hiroyuki Hori sicher nicht über solche Tricks rausgeholt,
solche Unterschiede schafft man nur, wenn man den Algorithmus
verstanden hat und CPU konform umstellt.
Alle Algorithmen in diesem Bereich kommen von irgendwelchen
Mathematikern denen es völlig reicht zwei Schleifen zu schachteln
alles in double zu rechnen und dann IDCT dran schreiben.

Schau dir mal die IDCT in MPEG2 Decodern von OpenSource Projekten an.
Begonnen hat es mit einer double IDCT, die dann abgelöst wurde durch
eine interger IDCT (fastIDCT) um dann einmal von Intel theoretisch in
MMX gelöst wurde. Intel hatte den Code freigegeben und Elecard
(glaube die gehören heute zu MainConcept) hat die Implementierung
dann veröffentlicht.

Nur so kann man zweistellige Prozente schaffen.

Gruß
Stefan