Performance frage static /dynamic memory!?


  • Mod

    @SoIntMan sagte in Performance frage static /dynamic memory!?:

    ok wenn kurz, solange ich den Speicher lineare durchiteriere (loop) den ich "dynamisch" allokiert habe macht es kein unterschied zu statischem Speicher?

    Ja.

    (allokiert mallock immer einen "ganzen" block).

    Ja.

    Wenn ich aber sporadisch hin und her springe bin ich bei statische schneller...?

    Nein. Außer eventuell doch ja, aber dann durch so komische Effekte, wie dass du bei statischer Allokation größenmäßig sehr beschränkt bist, so dass sowieso alles im Cache liegt. Aber das ist weiterhin keine Eigenschaft des statischen Speichers an sich, sondern davon, dass man damit weniger machen kann, was langsam sein könnte. Würdest du in einem kleinen Block dynamischen Speichers gelegentlich hin und her springen, wäre das genauso schnell wie in einem kleinen Block statischen Speicher gelegentlich hin und her zu springen. Wenn du die Größenlimits deines statischen Speichers ausschaltest und in einem riesigen Block gelegentlich hin und her springen, wäre es genauso langsam wie in einem riesigen Block dynamischen Speichers hin und her zu springen. Wie jetzt schon oft gesagt, gibt es keinen prinzipiellen technischen Unterschied zwischen statischen und dynamischen Speicher, sondern alle Unterschiede kommen daher, was man damit macht (Es gibt noch einen Unterschied darin, wie aufwändig die Anforderung eines neuen Blocks ist, aber das lassen wir mal außen vor, weil es hier um Unterschiede bei der Nutzung geht).

    std::list ist ja als linked list implementiert oder?

    Ja.

    da kann ja jedes element ganz woanders liegen?

    Ja.



  • @SeppJ sagte in Performance frage static /dynamic memory!?:

    Wie jetzt schon oft gesagt, gibt es keinen prinzipiellen technischen Unterschied zwischen statischen und dynamischen Speicher, sondern alle Unterschiede kommen daher, was man damit macht (Es gibt noch einen Unterschied darin, wie aufwändig die Anforderung eines neuen Blocks ist, aber das lassen wir mal außen vor, weil es hier um Unterschiede bei der Nutzung geht).

    Super Danke für deine Ausführungen, hat mir geholfen es zu verstehen. In meinen Fall ist das dann super.. da ich meinen speicher nur "einmal" bei initalisieren dynamisch allokcieren und nur noch verwende. Hätte eben gedacht wenn ich der speicher statisch ist, dass ich performance vorteile habe. Und vom caching her,passt es auch, weil ich auch keine wilden array sprünge mache:)


  • Mod

    Ich hoffe doch, dass das kein reales Beispiel war? Benutz in echtem Code bloß kein new/delete (außer du baust eigene Allokatoren o.Ä.)! Rule of 0!



  • @SeppJ sagte in Performance frage static /dynamic memory!?:

    Ich hoffe doch, dass das kein reales Beispiel war? Benutz in echtem Code bloß kein new/delete (außer du baust eigene Allokatoren o.Ä.)! Rule of 0!

    Nein war nur dummy code... aber sorry das verstehe ich jetzt nicht in c++ new/delete c malloc/free? oder wie meinst du das?

    im produktiv code c muss ich malloc/Free nehmen und .. in C++ smart ptr etc. also nicht nativ new/Delete;)



  • @SoIntMan sagte in Performance frage static /dynamic memory!?:

    @SeppJ sagte in Performance frage static /dynamic memory!?:

    Ich hoffe doch, dass das kein reales Beispiel war? Benutz in echtem Code bloß kein new/delete (außer du baust eigene Allokatoren o.Ä.)! Rule of 0!

    Nein war nur dummy code... aber sorry das verstehe ich jetzt nicht in c++ new/delete c malloc/free? oder wie meinst du das?

    Mit C++11 wurden smart pointer eingeführt, sodass man eigentlich kein new und delete mehr braucht.


  • Mod

    Was hast du denn mit Smart Pointern vor, was mit den fertigen Containern nicht besser geht?



  • @SeppJ sagte in Performance frage static /dynamic memory!?:

    Was hast du denn mit Smart Pointern vor, was mit den fertigen Containern nicht besser geht?

    doch geht bestimmt besser.. habe vll. die falsche foren seite.. bin in der C welt unterwegs...;)



  • @SoIntMan sagte in Performance frage static /dynamic memory!?:

    im produktiv code c muss ich malloc/Free nehmen und .. in C++ smart ptr etc. also nicht nativ new/Delete;)

    Manuelle Speicherverwaltung ist generell anfällig für Fehler. Ein klassischer Fall, eine etwas größere Funktion nutzt diverse allokierte Sachen und innerhalb der Funktion muss an diversen Stellen die Funktion beendet werden.

    Überall wo nun die Funktion sich beendet, müssen alle allokierten Ressourcen freigegeben werden. Wie macht man dies am besten und möglichst fehlerfrei?

    In so manchem alten DirectX Code von Microsoft sieht man da ein goto, was für C ok ist. In C++ nutzt man dagegen RAII.

    Nehmen wir mal z.B. die Klasse std::string. Diese allokiert intern einen Speicher, zur Speicherung des String. Füge ich Zeichen hinzu, so stellt die Klasse sicher dass der String vollständig gespeichert wird. Notfalls allokiert die Klasse einen größeren Speicher, kopiert die alten Daten rein, fügt die Zeichen hinzu und löscht den alten Speicher. Erreicht die Instanz das Lebensende, so löscht der Destruktor der Klasse automatisch die allokierten Ressourcen.

    Dadurch vereinfacht sich das Beenden einer Funktion erheblich, da automatisch die Ressourcen freigegeben werden und dadurch Speicherlöcher nicht mehr vorkommen.


  • Mod

    @SoIntMan sagte in Performance frage static /dynamic memory!?:

    bin in der C welt unterwegs...;)

    Das ging aus deiner Frage im C++-Forum mit C++-Code nicht so ganz klar hervor 😉



  • @SeppJ kein Ding;)



  • @SoIntMan sagte in Performance frage static /dynamic memory!?:

    ok wenn kurz, solange ich den Speicher lineare durchiteriere (loop) den ich "dynamisch" allokiert habe macht es kein unterschied zu statischem Speicher? (allokiert mallock immer einen "ganzen" block). Wenn ich aber sporadisch hin und her springe bin ich bei statische schneller...?

    Nein, wesentlich sind die Zugriffsmuster auf den Speicher. Moderne Computer nutzen mehrere Ebenen von Caches, so dass immer eine bestimmte Menge an Daten (Cache Lines) aus dem Hauptspeicher gelesen werden. Die erste Optimierung die man machen sollte, ist es die Cache Misses zu minimieren.

    Nehmen wir als simples Beispiel eine Matrizenmultiplikation für die Matrizen A, B, C mit A*B=C. Dann erhält man die Matrix C über die Beziehung

    cik=j=1naijbjkc_{ik}=\sum_{j=1}^n a_{ij} \cdot b_{jk}

    Das kann man nun ganz simpel mit drei verschachtelten Schleifen lösen, und ignoriert dabei die Cache Lokalität und der Algorithmus läuft langsam, oder man macht das so, dass man die Caches berücksichtigt.



  • @john-0 sagte in Performance frage static /dynamic memory!?:

    Das kann man nun ganz simpel mit drei verschachtelten Schleifen lösen, und ignoriert dabei die Cache Lokalität und der Algorithmus läuft langsam, oder man macht das so, dass man die Caches berücksichtigt.

    Hah. Richtig geraten, bevor ich auf den Link geklickt habe. Der Typ mit dem lustigen Informatiker-Nachnamen hat sich prominent mit dem Thema beschäftigt. Auf den stößt man dabei immer wieder 😉



  • @Finnegan Meinst du den Goto? Da scheint es aber mehrere von zu geben, ein Masaharu G. ist hier nämlich auch On-Topic, da er für CINT, einen C++-Interpreter, verantwortlich ist. (CINT war bis circa 2013 in ROOT drin, vor dem Umstieg auf das LLVM-basierte Cling).



  • @wob sagte in Performance frage static /dynamic memory!?:

    @Finnegan Meinst du den Goto? Da scheint es aber mehrere von zu geben, ein Masaharu G. ist hier nämlich auch On-Topic, da er für CINT, einen C++-Interpreter, verantwortlich ist. (CINT war bis circa 2013 in ROOT drin, vor dem Umstieg auf das LLVM-basierte Cling).

    Scheint ja ein häufigerer japanischer Nachname zu sein, falls die nicht verwandt sind. Ich mein aber schon Kazushige Goto, über den stolpert man schnell wenn man effiziente Methoden zur Matrixmultiplikation recherchiert.


Anmelden zum Antworten