Maximal mögliche Größe eines Objektes abfragen
-
Hallo Leute,
gibt es eine portable Möglichkeit die maximale Größe, die einem Objekt zugeordnet werden kann während der Laufzeit abzufragen?
Ich habe einen Schnipsel gefunden, allerdings ist er nur in C und wahrscheinlich schön lahm.
#include <stdlib.h> size_t GetAvailableMemory(void) { char *p,*q; size_t siz = 1; q = p = calloc(1,siz); while (q) { siz++; // Can be more to speed up things q = realloc(p,siz); if(q) { p = q; } } free(p); return siz; }
-
Ich sehe keinen Grund, warum man das wissen wollen sollte. Wenn du ein großes Objekt erstellen willst, dann probier es einfach aus, wenn es nicht klappt bekommst du eben deine Exception
-
314159265358979 schrieb:
Ich sehe keinen Grund, warum man das wissen wollen sollte. Wenn du ein großes Objekt erstellen willst, dann probier es einfach aus, wenn es nicht klappt bekommst du eben deine Exception
Ja.
-
Ich muss mit einer Datei rechnen die etwas größer ist also möchte ich eben die maximale Größe kennen. Sequentielles lesen ist schnell und man hätte gleich eine Menge zu rechen. Eine Exception nutzt in diesem Fall nichts.
-
Hier meine Vermutung der Dinge:
(1) Du liest so viel wie möglich auf einmal, meinetwegen 1GB. Dann musst du erst mal warten, bis dir die Festplatte die Daten vollständig übermittelt hast. Bei jeder weiteren Aktion hast du dauernd Cache Misses oder noch schlimmer Page Faults und musst auf den langsamen RAM oder auf die noch viel langsamere Festplatte zugreifen.
(2) Du liest blockweise, meinetwegen 1MB. Dann kannst du deine Daten im Cache halten und alle Aktionen gehen sehr flott. In der Zeit, in der du Berechnungen durchführst, werden bereits wegen der guten Prediction-Mechanismen die nächsten Daten von der Festplatte zumindest in den Cache der Festplatte geladen.
-
memory01 schrieb:
Ich muss mit einer Datei rechnen die etwas größer ist also möchte ich eben die maximale Größe kennen. Sequentielles lesen ist schnell und man hätte gleich eine Menge zu rechen. Eine Exception nutzt in diesem Fall nichts.
Dateigröße lesen, std::vector mit resize() auf passende Größe bringen, Datei in vector lesen, Drops gelutscht.
Falls die Datei richtig groß sein sollte (einige zig oder hundert MB) liest du sie besser sequenziell in einer festen Blockgröße, dazu musst du auch nicht rumprobieren, wie groß der maximal allozierbare Block ist.
-
Und das was du machen willst auch nicht. Wer sagt dir, dass nachdem die Funktion durchgelaufen ist, nicht ein anderes Programm genau an diese Stelle schreibt und der Speicher dann nicht mehr an einem Stück verfügbar ist und es zu einer exception kommt?
-
HighLigerBiMBam schrieb:
Und das was du machen willst auch nicht. Wer sagt dir, dass nachdem die Funktion durchgelaufen ist, nicht ein anderes Programm genau an diese Stelle schreibt und der Speicher dann nicht mehr an einem Stück verfügbar ist und es zu einer exception kommt?
Kannst du das ein wenig ausführen? So wie es da steht, verstehe ich es nicht.
-
Programm fragt, wie viel Speicher da ist. Ein anderes Programm nimmt sich einen Block in der Mitte. -> Dein Programm kann sich keinen Block in der ermittelten Größe holen
-
Michael E. schrieb:
Hier meine Vermutung der Dinge:
(1) Du liest so viel wie möglich auf einmal, meinetwegen 1GB. Dann musst du erst mal warten, bis dir die Festplatte die Daten vollständig übermittelt hast. Bei jeder weiteren Aktion hast du dauernd Cache Misses oder noch schlimmer Page Faults und musst auf den langsamen RAM oder auf die noch viel langsamere Festplatte zugreifen.
(2) Du liest blockweise, meinetwegen 1MB. Dann kannst du deine Daten im Cache halten und alle Aktionen gehen sehr flott. In der Zeit, in der du Berechnungen durchführst, werden bereits wegen der guten Prediction-Mechanismen die nächsten Daten von der Festplatte zumindest in den Cache der Festplatte geladen.
Den zweiten Punkt habe ich noch nicht in Betracht gezogen. Jeder Benchmark zeigt dir jedoch ein anderes Bild. Kleine Blöcke zu lesen geht immer langsamer als sequentiell alles abzugrasen.
Auch lohnt sich nicht mit kleinen Blöcken Threads aufzumachen weil die Verwaltung mehr Ressourcen mit sich bringt. Wenn ich jedoch mal 3GB auf einmal durchrechnen kann dann können auch die neuen Prozessoren> 4 Kerne was damit anfangen.
Übrigens: Die Datei ist etwas größer als 200GB. Diese in 1MB Blöcken zu lesen ist nicht gerade sinnvoll.
-
Ganz einfach er testet da den Speicher auf dem heap und reserviert solang bis es nicht weiter geht. dann wird free aufgerufen. Der Speicher ist somit freigegeben. Als nächstes plant er einfach so zu schreiben in der Annahme es sei genügend Platz vorhanden. Zwischen free und dem erneuten reservieren ist naturgemäß ein zeitlicher Abstand. In dieser Zeit kann jedes andere Programm den soeben getestete Speicherbereich in Anspruch nehmen.
Ganz abgesehen von der Tatsache, wer garantiert dir, dass dein Programm beim erneuten Anfordern von Speicher den selben Speicherbereich verwendet? Niemand.
-
314159265358979 schrieb:
Programm fragt, wie viel Speicher da ist. Ein anderes Programm nimmt sich einen Block in der Mitte. -> Dein Programm kann sich keinen Block in der ermittelten Größe holen
Achso. Wär aber ziemlich böse vom OS, meinem Programm die Speicherseite direkt zu entziehen, nur weil ich gerade Speicher freigegeben hab
Mit placement new wär man natürlich auf der sicheren Seite.
memory01: Wenn du das letzte an Speicher aus deinem (Windows-)System rauskitzeln willst, werden deine Daten ausgelagert und du hast nix gewonnen.
Mach doch mal den Praxistest. Du muss die Datei sowieso blockweise einlesen, wenn du nicht gerade 200GB Hauptspeicher zur Verfügung hast. Mach mal ein Benchmark mit unterschiedlichen Blockgrößen, am besten mit ähnlich aufwändigen Berechnungen wie sie später tatsächlich gemacht werden auf den Daten. Das Ergebnis würde mich auch interessieren
-
Von der Idee, dass mehr als ein Thread zum Rechnen irgendwelche Performance-Steigerungen bringt, wirst du dich eh verabschieden müssen, weil der Speicher hier der limitierende Faktor ist, wenn du nicht gerade sehr aufwändige Berechnungen durchführst.
-
Memory Mapped Files
das ist das Stichwort das hier wohl am interessantesten ist.
-
Michael E. schrieb:
Von der Idee, dass mehr als ein Thread zum Rechnen irgendwelche Performance-Steigerungen bringt, wirst du dich eh verabschieden müssen, weil der Speicher hier der limitierende Faktor ist, wenn du nicht gerade sehr aufwändige Berechnungen durchführst.
Threading bringt immer etwas bei > 10000 Berechnungen. Wenn es ein wenig aufwändiger ist, dann genügen schon 100 Operationen um eine Berechnung von 10sek auf 1sek zu drücken. Es ist immer Fall abhängig aber man sollte heute in jedem Fall an Threading denken.
So ganz Nebenbei: Der Berechnungsteil ist schon implementiert und funktioniert einwandfrei, mir geht es nur um die Speicherreservierung. Vielleicht hat jemand schon das gleiche Problem gehabt und einen clevereren Ansatz als eine while Schleife gefunden.
-
memory01 schrieb:
Threading bringt immer etwas bei > 10000 Berechnungen. Wenn es ein wenig aufwändiger ist, dann genügen schon 100 Operationen um eine Berechnung von 10sek auf 1sek zu drücken. Es ist immer Fall abhängig aber man sollte heute in jedem Fall an Threading denken.
Was genau verstehst du unter einer Berechnung? Ist das jetzt auf diesen konkreten Fall bezogen?
Zur Aussage an sich: Wenn dein Verarbeitungsthread für einen Block 1 Sekunde braucht, der Einlesethread zum Einlesen des nächsten Blocks aber 10 Sekunden, wie willst du dann durch parallele Verarbeitungsthreads die Geschwindigkeit erhöhen? Du wirst dir eher den Cache zerschießen.
So ganz Nebenbei: Der Berechnungsteil ist schon implementiert und funktioniert einwandfrei, mir geht es nur um die Speicherreservierung. Vielleicht hat jemand schon das gleiche Problem gehabt und einen clevereren Ansatz als eine while Schleife gefunden.
Dann könntest du doch ein wenig rumprobieren.
-
Was spricht dagegen einfach nen Konfigurationsparameter dafür zu verwenden? (.ini File, Commandline Parameter, ...)
Oder alternativ wie schon vorgeschlagen wurde eine fixe Blockgrösse zu verwenden die überall funktionieren wird. (Muss ja nicht 1 MB sein, 1x 100MB kann man sich auch auf "jedem" System leisten)Muss das System denn unbedingt "self tuning" sein, und die maxmiam sinnvoll mögliche Grösse selbst ermitteln?
-
314159265358979 schrieb:
Programm fragt, wie viel Speicher da ist. Ein anderes Programm nimmt sich einen Block in der Mitte. -> Dein Programm kann sich keinen Block in der ermittelten Größe holen
Das kann nur passieren, wenn "das andere Programm" im gleichen Adressraum läuft, d.h. im gleichen "Prozess".
Und dann würde ich es nichtmehr als "anderes Programm" bezeichnen, sondern höchstens als "anderen Programmteil".
-
Wieder was dazu gelernt