Automatisierte Performance Messungen


  • Mod

    nevermore schrieb:

    Klar, auch. Aber ich hab oben schon geschrieben, dass ich gerne auch zeigen möchte, wie nah ich an der Peak Performance der Architektur bin.

    Gib die Instruktionen pro Takt an. Instruktionen zählen, Zeit messen, dann hohe Mathematik (Division), fertig.



  • knivil schrieb:

    Dann schau doch wie die Testprogramme anderer Bibliotheken das machen, beispielsweise FFTW.

    Gute Idee 👍 Ich werde mal schauen, was ich so finde.

    knivil schrieb:

    Und wenn man dort etwas stoebert, dann findet man http://www.bitmover.com/lmbench/ .

    Das ist ein Benchmark für Unix Systeme. Floating Point Performance wird da gar nicht gemessen? Übersehe ich was?

    knivil schrieb:

    Bei FFTW warden alle Instruktionen hergenommen. Waere ja auch sinnlos andere zu nehmen. Denn was verhindert denn, maximale Flops zu erreichen? Na die Operationen, die keine Flops sind.

    Das stimmt so nicht, heutige CPUs haben ILP. Nicht-Flops spielen daher bei floating-point-lastigem Code kaum eine Rolle, man betrachtet sie daher gar nicht. Wenn ich alle Instruktionen mitrechne, kann ich meine gemessene Performance auch nicht mehr mit der Peak Floating Point Performance des Systems vergleichen. Woher hast du die Information zu FFTW?



  • SeppJ schrieb:

    nevermore schrieb:

    Klar, auch. Aber ich hab oben schon geschrieben, dass ich gerne auch zeigen möchte, wie nah ich an der Peak Performance der Architektur bin.

    Gib die Instruktionen pro Takt an. Instruktionen zählen, Zeit messen, dann hohe Mathematik (Division), fertig.

    Instruktionen pro Takt ist doch das selbe wie Flop/s, nur dass die Taktfrequenz rausgerechnet ist? Das ist ja das was ich haben will, nur in einer anderen Einheit. Problem ist das Instruktionen zählen. Das würde ich gerne automatisieren. Zur Not muss ich den Code mit Countern instrumentieren, ich hatte nur gehofft dass es eine einfachere Lösung gibt.



  • knivil schrieb:

    Denn was verhindert denn, maximale Flops zu erreichen?

    -latenz von instruktionen bsp:

    idiv eax,ebx
    add eax,5 ;stall bis idiv fertig ist
    

    -durchsatz von instruktionen bsp:

    imul eax,ebx
    imul ecx,ebx ;//stall 1cycle auf atom cpus
    

    -latenz von cache misses (bsp linked list von 4GB)
    -bandbreite (linear durch 4GB von floats durchgehen und davon "max" bestimmen -> 400ms -> '5gflops' aufs cpus die 100gflops+ schaffen)
    -auslastung einzelner cpu units bsp

    fdiv ;cycle 0
    fmul ;cycle 1
    

    vs

    fadd ;cycle 0
    fmul ;cycle 0
    

    Na die Operationen, die keine Flops sind.

    das ist eher nicht der fall, wenn man code hat der wirklich viel rechnet, da bei AMD diese instruktionen in ganz unabhaengigen pipelines abgearbeitet und bei Intel die pipeline genug durchsatz hat um float und anderweitige einheiten zu fuettern (im schnitt wohl ca 2.4einheiten/cycle).
    natuerlich ist das nicht der fall bei etwas wie quicksort, selbst wenn man floats vergleichen wuerde, aber dabei wuerde man wohl auch nicht die gflop leistung optimieren wollen.

    ich finde das vorgehen vom threadstarter gut, ich rechne (bzw schaetze) immer erst die potentiel moegliche leistung aus, bevor ich anfange zu optimieren, wie sonst kann man wissen wann man fertig ist? (wenn einem die ideen ausgehen? 🤡 )

    statt instruktionen zu zaehlen, kann man manchmal auch die groesse des problems analysieren und so errechnen wieviele 'flops' noetig sind um das problem zu loesen, das klappt auch mit komplexeren algorithmen.
    ich habe zudem einen wrapper um alle SIMD instruktionen, der im profiling mode einen counter hochzaehlt (pro instruktionen um zu wissen was genau stallt).
    leider hab ich die gunst tools zu nutzen die nicht so leicht zugaenglich sind, deswegen kann ich nichts wirklich empfehlen (ich glaube pix fuer windows hat keine tolle cpu analyse, wenn ich mich recht entsinne), frueher hab ich immer vtyne genutzt, das ist ja auch kostenlos fuer linux zu haben, wuerde ich auf jedenfall mal ausprobieren 😉



  • Hmmm, danke für den Input. Das mit den Wrappern um die SIMD Intrinsics ist ganz pfiffig. Leider würde ich das ganze gerne schon auf einen Code anwenden, an dem noch nichts optimiert wurde und daher auch noch keine Instrinsics verwendet werden.

    Scheint wohl wirklich keine einfache Lösung zu geben. Ich schaue mir nochmal VTune an und welche Performance Counter mir das so anbietet.



  • nevermore schrieb:

    Hmmm, danke für den Input. Das mit den Wrappern um die SIMD Intrinsics ist ganz pfiffig. Leider würde ich das ganze gerne schon auf einen Code anwenden, an dem noch nichts optimiert wurde und daher auch noch keine Instrinsics verwendet werden.

    das ist nicht anders, du kannst dir ein typedef machen

    typedef float REAL;
    

    basteln, und alles an floats darauf umstellent (sollte fast komplett mit replace-all gehen).
    und zum benchmarken erstellst du dir eine float klasse mit den basis operationen und casts und dann

    typedef MyFloat REAL;
    

    und schon hast du deine antworten 😉



  • Perfekt, so mach ich es! Ist zwar eine Lösung auf Sourcecodeebene, aber die Änderungen sind minimal. Und wenn ich den Code ändere, muss ich die Zählung nicht anpassen. Ich hatte mir nämlich schonmal für ein anderes Projekt ein paar Makros zum Zählen gebaut, so in der Art von INCREASE_FLOP_COUNTER(...), aber das ist natürlich sehr fehleranfällig.

    Das Beste: Den typedef gibt es eh schon, um von float auf double umzuschalten. Einfacher geht's nicht 🙂

    Danke 👍



  • @rapso: Ich weiss, was alles die Performance drueckt. Ich sehe kein Beispiel das speziell fuer floating point operations gedacht ist.



  • knivil, es kommt natürlich auf den Algorithmus an. Aber oft ist es eben so, dass hauptsächlich Floating Point Operationen benötigt werden. Das bisschen Integerarithmetik etc. macht die CPU dann nebenbei (ILP, Superskalarität) und kann ignoriert werden.

    Bei FFTs ist das auch der Fall. Du hattest ja FFTW angesprochen: die rechnen einfach mit 5*n*log n Floating Point Operationen in ihren Benchmarks. Aus dem FFTW Paper (http://www.fftw.org/fftw-paper-ieee.pdf):

    We show the benchmark results as a series of graphs. Speed is measured in “MFLOPS,” defined for a transform of size n as (5n log2 n)/t, where t is the time in µs for one transform, not including one-time initialization costs. This count of floating-point operations is based on the asymptotic number of operations for the radix-2 Cooley-Tukey algorithm (see [17, page 45]), although the actual count is lower for most DFT implementations

    rapsos Beispiele zeigen nur, dass auch andere Dinge als non-flops die Floating Point Performance drücken.



  • knivil schrieb:

    @rapso: Ich weiss, was alles die Performance drueckt.

    deine aussage, von der sache die am wenigsten einfluss hat bei algorithmen bei denen man gflops misst, hat den gegenteiligen anschein bei mir hinterlassen, oder hab ich sarkasmus uebersehen? 😕

    Ich sehe kein Beispiel das speziell fuer floating point operations gedacht ist.

    meine beispiele? die waren zumeist auf float bezogen bzw kann man die darauf anwenden.



  • rapso schrieb:

    ich finde das vorgehen vom threadstarter gut, ich rechne (bzw schaetze) immer erst die potentiel moegliche leistung aus, bevor ich anfange zu optimieren, wie sonst kann man wissen wann man fertig ist? (wenn einem die ideen ausgehen? 🤡 )

    😕 Wie rechnest du die potentiel mögliche Leistung aus? Leistung in was?


Anmelden zum Antworten