Wie programmiere ich performant? Literaturtipps?



  • Hättest ja auch mal am Anfang schreiben können was du vor hast. Zuerst solltest du mal mit nem Profiler schauen, was wirklich lange braucht. Dann schaust du ob es für diesen Teil (oder den darum) nen besseren Algorithmus gibt. Wenn nicht, kannst du immer noch versuchen den Code zu optimieren, wobei du damit wahrscheinlich nur ein paar Prozent gewinnen kannst, außer du hast wirklich schlecht programmiert.



  • @soerenP: Auch bei Audio Signalverarbeitung gibts verschiedene Algorithmen die man für die selbe Aufgabe verwenden kann. Einen FIR Filter kann man z.B. stur mit Kreuzkorrelation berechnen, oder mit Hilfe einer FFT/IFFT, was viel schneller geht.



  • hustbaer schrieb:

    Einen FIR Filter kann man z.B. stur mit Kreuzkorrelation berechnen, oder mit Hilfe einer FFT/IFFT, was viel schneller geht.

    normalerweise wird, aus geschwindigkeitsgründen, bei FIR filtern mit konstanten gearbeitet, so dass man zur laufzeit keine aufwendigen berechnungen wie FFT mehr machen muss.
    🙂



  • @DSP-freak:
    Ich weiss nicht genau was du meinst. Ich spreche von langen FIR Filtern wo nahezu alle Koeffizienten ungleich 0 sind - was willst du da mit "Konstanten" optimieren?



  • mit konstanten meinte ich die koeffizienten. sampling-wert kommt in einen ringuffer, dann werden alle elemente des buffers mit dem dazugehörigen koeffizienten multipliziert, der output berechnet (z.b. mittelwert von allem). danach wird der buffer eins weitergeschoben, wobei das älteste element rausfliegt. usw.usw..
    🙂



  • Mein lieber DSP-Freak,
    dann hast du wohl noch nie FIR-Filter mit längeren koeffizientensätzen probiert... (ohne DSP) Da geht nämlich ohne FFT-Faltung gar nichts. Und die muss man wohl zur laufzeit durchführen, die koeffizienten kann man zwar vorher transformieren, aber der Audio-Input ist (zumindest bei mir 😉 ) immer noch zur Laufzeit erstellt...
    Falls dir das Prinzip ungeläufig ist:
    Input und Koeffizienten werden über FFT in den Frequenzbereich transformiert, dort wird eine komplexe Multiplikation durchgeführt, was viel schneller geht als eine Faltung (n berechnungen anstatt n*n) da die FFT ab einer bestimmten Puffergröße viel schneller ist als eine normale Transormation (die so lange dauern würde wie die brute force faltung) kann man so immens Zeit sparen.
    @alle anderen:
    Ja, klar kann ich über die richtigen Algorithmen Zeit sparen, wie man sieht, aber wenn man mal keinen Standard braucht, wer sagt mir, wie ich vorgehen soll?
    Ich bin mir sicher, dass in meinem Programm so unglaubliche Schnitzer drin sind, für deren verbesserung mir bestimmt kein Algorithmen-Buch hilft.
    Algorithmen sind ja auch eher Mathematischer Natur. Ich meine, ein Algorithmus kann bestimmt ganz toll sein (z.B. FFT), ein ahnungsloser Mathematiker könnte ihn aber unter Umständen sehr schlecht in Code übersetzen, z.B. weil er nicht weiss, dass Speicherzugriff auch Zeit kostet, oder wie auch immer. Versteht ihr, was ich meine?
    Viele Grüße
    Sören



  • Nochmal, um meine Misere etwas zu erläutern:
    Ich bin dabei, einen Synthesizer für die VST-Schnittstelle zu basteln. Läuft auch, alles kein Thema. Er basiert auf dem Karplus-Strong algorithmus, im Prinzip nur eine Verzögerung, die der Periodendauer entspricht, eine Anregungsfunktion und ein Filter, der die Höhen rausnimmt im Verlauf der Schwingung. (den ich aber auch deaktiviert habe, um zu schauen, wieviel Leistung er frisst). Alles mit Sicherheit kein Hexenwerk. Wenn ich davon aber 5 Stimmen Spiele (ohne Filter) ist mein Turion Dual Core schon zu 50% ausgelastet. Da ist bestimmt was ziemlich im Argen und meine Algorithmen sind meiner Meinung nach so simpel, dass sie nicht wirklich zu vereinfachen sind. Ich bin fast der Meinung, dass man die eigentlich nicht so schlecht hinbekommen kann, dass ich ein solches Ergebnis bekomme...
    Naja...
    Grüße
    Sören



  • hast du jetzt schon mal nen profiler verwendet?



  • Just in diesem Moment habe ich den CodeAnalyst von AMD mal angeschmissen.Und wollte auch gleich eine Frage dazu stellen.
    Also: Der Analyst zeigt an, dass die meiste Zeit "an der ersten Klammer meiner Funktionen" verbraucht wird. Was sagt mir das? Würde da inline was helfen, weil ich da nicht für jeden Aufruf jede Menge quatsch auf den Stack schreibe (vorsicht, Halbwissen)? Wie kann ich den Plot, bzw. die Timesamples, überhaupt interpretieren?
    Heißt das konkret, wieviel Zeit der Prozessor mit einem bestimmten Befehl beschäftigt ist?
    Hab mal die ASM-übersetzuung angeschaut. Die meiste Zeit (über 50%) verbringt er mit:

    rep stosd es:[edi]
    

    und zwar bei jeder funktion. Weiss jemand, was das heißt?
    Grüße
    Sören



  • Wenn du unter Windows programmierst könnte ich aus eigener Erfahrung:
    http://www.glowcode.com/
    empfehlen. Der ist einfach zu verwenden und der Output ist, meines
    Erachtens, nahezu selbsterklärend.



  • Kenn den CodeAnalyst nicht. Aber kann es sein, dass du ne große Struktur/Klasse oder was anderes großes als Kopie und nicht als Pointer/Referenz übergiebst?



  • hmmm...... schrieb:

    Kenn den CodeAnalyst nicht. Aber kann es sein, dass du ne große Struktur/Klasse oder was anderes großes als Kopie und nicht als Pointer/Referenz übergiebst?

    Eigentlich nicht, weder in dieser funktion (die ist void (void)) noch in irgendwelchen anderen Funktionen übergebe ich Objekte oder Strukturen, wenn dann als Pointer. Meine betroffenen funktionen sind alle void (void) oder seltener float (void) und zuletzt float (float).
    Vielleicht hat der Compiler ne falsche Einstellung?
    Ist der VC++ 2005 Express Edition-Compiler.
    Grüße
    Sören



  • Wie ich das jetzt rausgefunden habe, hat der rep stosd den zweck, Daten zu kopieren, in meinem Falle die unnützen Daten aus eax (cccccccch) 33h-mal an [edi]etc...pp... zu kopieren. Warum schreibt mein dummer Compiler das an den Anfang meiner Funktion?
    Grüße
    Sören

    Achja, Worauf edi zeigt? Keine Ahnung, es gab ein

    mov ebp,esp
    lea edi,[ebp-000000cch]
    

    vorher, mehr weiß ich nicht.



  • ich wuerde vermuten dass du riesige datenmengen per value uebergibst oder zumindestens riesige datenmengen zuweist (kann auch ein ctor einer localen variable sein der das macht).



  • Mit Exception Handling wie try catch oder __try __except kann es nichts zu tun haben?



  • rapso schrieb:

    ich wuerde vermuten dass du riesige datenmengen per value uebergibst oder zumindestens riesige datenmengen zuweist (kann auch ein ctor einer localen variable sein der das macht).

    Nö, tut mir leid. Als lokale Variablen gibts nur einfache floats und ints. Funktionen sind, wie gesagt ohne oder nur mit float-parameter.
    Es gibt auch sonst keinen sinnvollen Grund in einen 33h - mal 4 ByteGroßen Speicher cccccccch reinzuschreiben, oder?
    Aber im Laufe meiner Nachforschungen habe ich rausgefunden, dass genau der Code auch bei anderen Funktionen (nicht von mir, siehe hier:
    http://forums.devshed.com/c-programming-42/convert-c-to-assembly-language-183227.html vorne dran gehängt wird. Kann doch nicht Sinn der Sache sein, oder? Vielleicht sollte ich mal im Assembler-Forum nachfragen.
    Grüße
    Sören



  • yogle schrieb:

    Mit Exception Handling wie try catch oder __try __except kann es nichts zu tun haben?

    Hmmm, auch nicht. Hab in meinem kompletten Code kein __try drin



  • soerenP schrieb:

    rapso schrieb:

    ich wuerde vermuten dass du riesige datenmengen per value uebergibst oder zumindestens riesige datenmengen zuweist (kann auch ein ctor einer localen variable sein der das macht).

    Nö, tut mir leid. Als lokale Variablen gibts nur einfache floats und ints. Funktionen sind, wie gesagt ohne oder nur mit float-parameter.
    Es gibt auch sonst keinen sinnvollen Grund in einen 33h - mal 4 ByteGroßen Speicher cccccccch reinzuschreiben, oder?

    doch, debuggen.



  • Du kompilierst aber nicht im debug modus bei der performance messung?

    Kannst die die Codestellen mal zeigen (funktion+aufruf)?



  • Ok, stimmt, wenn ich nicht debugge, schmeißt er anderen Code raus, der auch nicht wesentlichs schneller ist, aber die o.g. Aufrufe nicht hat. Vielleicht versteh ich den Profiler auch nicht so ganz. Jetzt zeigt er mir an, dass ein fstp ca.40% der Rechenzeit einer Funktion verbaucht. Kann ja auch nicht wirklich sein, oder?
    Ich probier mal den Glowcode aus..[edit: NOOOOOOOT, wer gibt mir die 499$]


Anmelden zum Antworten