Was braucht mehr Rechenleistung,...



  • sC++k schrieb:

    Und was wäre denn zu beachten um in so einer Lage auf jeden Fall Rechenaufwand
    zu sparen?

    Du solltest einen Profiler nehmen oder den Assemblercode anschauen. Vorausgesetzt natürlich, du hast wirklich keine grösseren, offensichtlichen Performanceprobleme und musst dich mit derartigen Mikrooptimierungen herumschlagen.

    Übrigens, das Forum kann Zeilen automatisch umbrechen 😉

    P.S. Yeah, die Vorschau geht wieder 🕶



  • Nexus schrieb:

    offensichtlichen Performanceprobleme und musst dich mit derartigen Mikrooptimierungen herumschlagen.

    Du meinst also der Unterschied sei kaum warnehmbar,
    auch wenn man solche eine Rechenoperation ins millionen- o. milliardenfache skripted/skripten lässt?

    Andere Frage:
    Hängt die Dauer der Berechung/Verrechnung u. der Arbeitsspeicherverbrauch zweier Variablen von der Größe der beeinhaltenden/zu berechnenden Zahlenwerte ab?



  • sC++k schrieb:

    Nexus schrieb:

    offensichtlichen Performanceprobleme und musst dich mit derartigen Mikrooptimierungen herumschlagen.

    Du meinst also der Unterschied sei kaum warnehmbar,
    auch wenn man solche eine Rechenoperation ins millionen- o. milliardenfache skripted/skripten lässt?

    Andere Frage:
    Hängt die Dauer der Berechung/Verrechnung u. der Arbeitsspeicherverbrauch zweier Variablen von der Größe der beeinhaltenden/zu berechnenden Zahlenwerte ab?

    Wenn du das durch ein Skript erledigst liegt dein Performance Bottleneck an einer ganz anderen Stelle. Da brauchste dir auch keine Gedanken über die Variablengröße machen...



  • DocShoe schrieb:

    Da brauchste dir auch keine Gedanken über die Variablengröße machen...

    Ich will aber 😋



  • Wenn du z.B. zwei Additionen vs. eine Division antreten lässt, dann werden wohl die zwei Additionen gewinnen.
    Wenn du die selben Rechenoperationen gegeneinander antreten lässt, dann wird die Variante mit zwei Operationen maximal gleich schnell sein, oft auch langsamer.

    Ausgenommen vielleicht diverse sehr eigenartige Spezielfälle, die aber real keinen interessieren.

    sC++k schrieb:

    DocShoe schrieb:

    Da brauchste dir auch keine Gedanken über die Variablengröße machen...

    Ich will aber 😋

    Tu was du nicht lassen kannst.



  • Mit der modernen Prozessorarchitektur sind überhaupt rechenoperationen annähernd kostenlos. Was Zeit braucht ist die Daten in den Prozessor zu bekommen.

    Vor einigen Tagen hatten wir in der Uni eine Tabelle, die die Relationen gezeigt hat:

    - Plus-Operation 1 Taktzyklus
    - Speicherzugriff auf Level-1 Cache: 1 Taktzyklus
    ...
    - Speicherzugriff auf Level-3 Cache: ~300 Taktzyklen
    ...
    

    Das bedeutet, es interessiert kaum bis gar nicht in der Praxis wie schnell (oder langsam) eine Rechenoperation ausgeführt werden kann, sondern der Bottleneck liegt beim Speicher.



  • Skym0sh0 schrieb:

    Mit der modernen Prozessorarchitektur sind überhaupt rechenoperationen annähernd kostenlos. Was Zeit braucht ist die Daten in den Prozessor zu bekommen.

    Vor einigen Tagen hatten wir in der Uni eine Tabelle, die die Relationen gezeigt hat:

    - Plus-Operation 1 Taktzyklus
    - Speicherzugriff auf Level-1 Cache: 1 Taktzyklus
    ...
    - Speicherzugriff auf Level-3 Cache: ~300 Taktzyklen
    ...
    

    Das bedeutet, es interessiert kaum bis gar nicht in der Praxis wie schnell (oder langsam) eine Rechenoperation ausgeführt werden kann, sondern der Bottleneck liegt beim Speicher.

    Und sowas hinterfragst Du ehlich nicht? Ist da mit Level-3-Cache die Festplatte gemeint?



  • sC++k schrieb:

    ...EINE Rechenoperation mit EINER Variable in der Größe von ➡ "4 BYTE"
    o.
    ...ZWEI Rechenoperationen mit ZWEI Variablen in der Größe von jeweilig ➡ "2 BYTE"?
    Diesmal erst die Frage dann die Begrüßung.

    wenn die operation eine multiplikation ist und du auf uint32_t bzw uint16_t arbeitest und der processor eine SPU ist, dann dauert eine uint32_t multiplikation 5cycle und eine uint16_t multiplikation 1cycle, zwei davon sind also 2.5mal schneller.
    ich hoffe das hilft dir weiter.

    volkard schrieb:

    Ist da mit Level-3-Cache die Festplatte gemeint?

    HDD latenzen sind meistens in ms angeben. In cycles gibt man die latenz von processoren an, da diese natuerlich mit der taktung des prozessors variiert.



  • volkard schrieb:

    Und sowas hinterfragst Du ehlich nicht? Ist da mit Level-3-Cache die Festplatte gemeint?

    Wodrauf willst du hinaus?

    Das Ding ist doch, dass, je tiefer wir in der Speicherhierarchie gehen, der Zugriff langsamer wird, umgekehrt aber der verfügbare Platz größer wird.

    Woebi ich mich grad selbst verbessern muss:

    - Register -> 200 ps
    - L1 Cache (auf der CPU) -> 1 ns
    - L2 Cache (auch auf der CPU) -> 10 ns
    - RAM -> 100 ns
    - HDD -> 5 ms
    - z.B FTP -> x s (beliebig)
    

    Meine obige Angabe war also tatsächlich etwas falsch. Wobei der Unterschied zwischen Register und RAM sich doch um den Faktor 500 unterscheiden. Und wenn ein Taktzyklus eben 200 Picosekunden braucht (-> 5GHz Prozessor), dann ist meine obige Angabe schon relativ gut stark unterschätzend.

    Letztlich bleibt jedoch nur meine Aussage, dass es relativ lange braucht, Daten in den Prozessor zu schaffen, als diese Daten durch einzelne Berechnungen zu verändern. Oder siehst du das anders?

    (Früher wars ja genua umgekehrt. Da hat man Daten flott in die CPU bekommen, aber die Berechnung war langsam.)


  • Mod

    Skym0sh0 schrieb:

    Letztlich bleibt jedoch nur meine Aussage, dass es relativ lange braucht, Daten in den Prozessor zu schaffen, als diese Daten durch einzelne Berechnungen zu verändern. Oder siehst du das anders?

    Verwechsele Latenz nicht mit Rechenzeit! Es mag zwar 100 ns dauern bis der Hauptspeicher antwortet, aber dann kommen mit der Antwort auch gleich 8 Bytes und das viele Milliarden mal pro Sekunde, ohne weitere Verzögerung. Mehr als genug, um den Prozessor voll zu beschäftigen, außer bei den allertrivialsten Rechnungen. Wenn du also nicht bloß genau zwei Byte aus dem Hauptspeicher verarbeiten möchtest, die aus irgendeinem Grund nicht schon längst in einem Prozessorregister liegen, dann ist der Speicher nicht der Flaschenhals. Und das ist der Normalfall.



  • Jain, würde ich nicht unbedingt behaupten.

    Arbeiten wir auf einem Array und verarbeiten sequenziell die Daten eines .B. Arrays dann geht das wahnsinnig schnell.

    Aber holen wir uns mal grad von Position x ein Datum, dann von Position y und dann von z etwas, dann dauert das schon recht lange. (Klar liegt hier eine Verantwortung beim Programmierer...)



  • SeppJ schrieb:

    Verwechsele Latenz nicht mit Rechenzeit! Es mag zwar 100 ns dauern bis der Hauptspeicher antwortet, aber dann kommen mit der Antwort auch gleich 8 Bytes und das viele Milliarden mal pro Sekunde, ohne weitere Verzögerung. Mehr als genug, um den Prozessor voll zu beschäftigen, außer bei den allertrivialsten Rechnungen.

    Normalerweise ist ja der L1-Cache darauf ausgelegt, den Prozessor zu saturieren. RAM ist Faktor 50-100 langsamer. Also so ziemlich alle operationen unter exp stoßen damit an das Speicherbottleneck. Das merkt man sehr schnell, wenn man mal matrix-vektor produkte benchmarkt. Wenn die Matrix nicht in den Cache passt, tut das der performance richtig weh. Also so 5 floating point multiplikationen sollte man schon machen, bevor man das nächste element vom speicher nimmt.

    ich wollte das schon immer mal Benchmarken, wieviele multiplikationen man da pro element braucht...


  • Mod

    Etwas, das < 5 Multiplikationen benötigt würde ich unter triviale Berechnung verbuchen.



  • otze schrieb:

    SeppJ schrieb:

    Verwechsele Latenz nicht mit Rechenzeit! Es mag zwar 100 ns dauern bis der Hauptspeicher antwortet, aber dann kommen mit der Antwort auch gleich 8 Bytes und das viele Milliarden mal pro Sekunde, ohne weitere Verzögerung. Mehr als genug, um den Prozessor voll zu beschäftigen, außer bei den allertrivialsten Rechnungen.

    Normalerweise ist ja der L1-Cache darauf ausgelegt, den Prozessor zu saturieren. RAM ist Faktor 50-100 langsamer. Also so ziemlich alle operationen unter exp stoßen damit an das Speicherbottleneck. Das merkt man sehr schnell, wenn man mal matrix-vektor produkte benchmarkt. Wenn die Matrix nicht in den Cache passt, tut das der performance richtig weh. Also so 5 floating point multiplikationen sollte man schon machen, bevor man das nächste element vom speicher nimmt.

    vielleicht bei vector dot vector, aber matritzen multiplikationen sind sehr cache freundlich. die benchmarks die gemacht werden bei sowas sind normalerweise viele MB gross, da passt wenig in den L1, allerdings kannst du die operationen so anlegen, dass sie cache freundlich sind. jedes element einer N*N matrix wird N mal mit einer ganzen zeile bzw spalte multipliziert. reuse ist also sehr hoch.
    entsprechend kann intel jedesmal wenn sie die rechenleistung verdoppel und die bandbreite um magere 10% oder so steigt, trotzdem 80% ihres theoretischen GFlop wertes rausbekommen.
    z.b. wenn man 50% mehr cores hat http://www.intel.com/content/www/us/en/benchmarks/server/xeon-e5-2600-v2/xeon-e5-v2-hpc-matrix-multiplication.html
    steigt die performance um 48% bei der matrix multiplikation in Linpack. und falls du dich wunders wie gross die matrix ist:

    For HPL What problem size N should I run ?

    In order to find out the best performance of your system, the largest problem size fitting in memory is what you should aim for. The amount of memory used by HPL is essentially the size of the coefficient matrix. So for example, if you have 4 nodes with 256 Mb of memory on each, this corresponds to 1 Gb total, i.e., 125 M double precision (8 bytes) elements. The square root of that number is 11585. One definitely needs to leave some memory for the OS as well as for other things, so a problem size of 10000 is likely to fit. As a rule of thumb, 80 % of the total amount of memory is a good guess. If the problem size you pick is too large, swapping will occur, and the performance will drop. If multiple processes are spawn on each node (say you have 2 processors per node), what counts is the available amount of memory to each process.

    quasi: je groesser die matrix, desto besser fuer dich.

    ich wollte das schon immer mal Benchmarken, wieviele multiplikationen man da pro element braucht...

    das kannst du leicht ausrechnen, ein core kann 2float operationen durchfuehren, die komplexeste ist FMAC, was also *+ ist und das kann ein intel core auf 8floats dank AVX2. wenn ich mich nicht verrechne, konsumierst du also 32flots ->128byte pro operation, bei 4GHz sind das ca 512GB/s. ein quad channel system von intel auf dem 2011 socket kann da 51.2GB/s schaffen (zufall? :D), du kannst also 5multiplikationen und 5additionen pro speicher transaktion machen. theoretisch.



  • SeppJ schrieb:

    Etwas, das < 5 Multiplikationen benötigt würde ich unter triviale Berechnung verbuchen.

    er meint 5 pro speicher zugriff, ob es trivial ist haengt dann von der datenmenge ab.


  • Mod

    rapso schrieb:

    SeppJ schrieb:

    Etwas, das < 5 Multiplikationen benötigt würde ich unter triviale Berechnung verbuchen.

    er meint 5 pro speicher zugriff

    Ich auch.

    Wenn du einfach nur die Summe von 1 GB Zahlen berechnen willst, ja, dann ist der Hauptspeicher zu langsam für die CPU. Das meine ich mit trivialer Rechnung: Den Rechenaufwand pro Zahl (Im Beispiel also eine Addition). Und 5 FPU-Multiplikationen pro Wert sind (wenn die Zahlen stimmen) schon genug um mit der Speicherpipeline die CPU 100% auszulasten. Das ist wirklich keine ungewöhnlich komplexe Rechnung -> trivial.



  • rapso schrieb:

    vielleicht bei vector dot vector, aber matritzen multiplikationen sind sehr cache freundlich. die benchmarks die gemacht werden bei sowas sind normalerweise viele MB gross, da passt wenig in den L1, allerdings kannst du die operationen so anlegen, dass sie cache freundlich sind. jedes element einer N*N matrix wird N mal mit einer ganzen zeile bzw spalte multipliziert. reuse ist also sehr hoch.

    Das ist mir alles bekannt 🙂 deswegen habe ich ja explizit matrix dot vector gemeint. Da sieht das nämlich optimiert so aus:
    http://download.tuxfamily.org/eigen/btl-results-110323/matrix_vector.pdf

    und da kannst du nichts dran machen, auch wenn der reuse des vektors hoch ist.

    das kannst du leicht ausrechnen, ein core kann 2float operationen durchfuehren, die komplexeste ist FMAC, was also *+ ist und das kann ein intel core auf 8floats dank AVX2. wenn ich mich nicht verrechne, konsumierst du also 32flots ->128byte pro operation, bei 4GHz sind das ca 512GB/s. ein quad channel system von intel auf dem 2011 socket kann da 51.2GB/s schaffen (zufall? :D), du kannst also 5multiplikationen und 5additionen pro speicher transaktion machen. theoretisch.

    hübsch. Danke!


Anmelden zum Antworten