Performance benchmarken, echte verbrauchte Zeit/Zyklen (Win2K) [gelöst]



  • Hi,

    ich möchte einige meiner Funktionen auf Effizienz testen und habe auch schon mit dem PerformanceCounter von Windows Erfolge erzielt. Leider bekommt die Konsolenanwendung, in der ich die Funktion teste, keine volle CPU Zeit. Wie kann ich es also anstellen, die zugeteilte CPU Zeit zu ermitteln? Ich möchte nur eine Routine benchmarken und möchte dafür nicht das Programm auf höchster Priorität laufen lassen. Das genialste wär, wenn ich die exakten CPU Zyklen bekommen könnte, die mein Programm schon verbraucht hat.

    Danke



  • GetProcessTimes hilft dir vielleicht weiter 🙂



  • danke flenders

    meine Lösung:

    // windows.h needed
    long long processtime() {
    	long long ctime, etime, ktime, utime;
    	bool result = GetProcessTimes(GetCurrentProcess(), (FILETIME*)&ctime, (FILETIME*)&etime, (FILETIME*)&ktime, (FILETIME*)&utime);
    	if (!result) return 0;
    	return (ktime + utime); // 100 ns = 1s/10000000 = 1E-7
    }
    

    Die Funktion gibt die verbrauchte (Kernel- und User-) Zeit des Programms in Zehnmillionstel (1 / 10 000 000) Sekunden zurück.

    GetProcessTimes()
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getprocesstimes.asp

    GetCurrentProcess()
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getcurrentprocess.asp

    Warum schwankt der Verbrauch jetzt immernoch um einige Zehn Millisekunden, obwohl bei jedem Programmdurchlauf haargenau das gleiche im Programm abläuft? Das Programm ist sehr speicherintensiv (also alloc/free von ints und kleinen Objekten, Anzahl im einstelligen Millionenbereich) und benutzt Rekursion bis höchstens 10. Grad.



  • Der Verbrauch hängt wohl auch noch ein wenig davon ab, wie viele Seiten-Fehler (so hießt das glaub') beim Speicher-Zugriff entstehen und wie auf in den Kernel-Modus gewechselt wird etc.
    Aber "einige Zehn Millisekunden" sind doch dann bei dieser Dimension eigentlich nicht so wahnsinnig viel 😉



  • och, die Ausführung braucht wenige hundert Millisekunden für mehrere Millionen Funkionsaufrufe. Laut Benchmark soll die Funktion 200-300 Zyklen pro Durchlauf verbrauchen... dabei wird manchmal (etwa 10 bis 100 Mal insgesamt) Speicher angefordert (ein Listenobjekt) und etwas Speicher umkopiert, und hier und da ein Objekt angelegt und dynamische Listen erweitert (eine echte Performance Liste, nicht verkettet).
    Wenn sich jemand für den Code interessiert, einfach melden.

    Lustiger Weise hat die ktime (Kernel Mode Zeit) Variable in meiner Funktion immer den Wert 0. Was ist Kernelmodus und warum geht mein Programm da rein?
    Danke



  • c.rackwitz schrieb:

    Lustiger Weise hat die ktime (Kernel Mode Zeit) Variable in meiner Funktion immer den Wert 0. Was ist Kernelmodus und warum geht mein Programm da rein?

    Afaik wird z.B. bei Funktionen wie WaitForSingleObject in den Kernelmodus gewechselt. Dann macht der Thread erstmal nichtsmehr, bis er eben von Windows wieder aktiviert wird. 🙂


Anmelden zum Antworten