speicher auf Festplatte wenn Virtueller Speicher nicht zur Verfügung steht.



  • Hallo libe C Gemeinde,
    ich hab folgendes Problem:

    Ich lese eine Text Datei mit 5000 000 Zeilen und mehr in einen 2 Dimensionalen double Array ein. Ich reserviere dafür mit Hilfe der Funktion malloc Speicher indem ich die Zeilen und Spalten der Textdatei ermittel.

    Jetzt hab ich natürlich nicht uendich viel RAM zur verfügung und 5000 000 sind ne ganze Menge. Wie ist es möglich den Speicher auf dei Festplatte auszulagern. Hat so etwas schon mal jemand gemacht???

    Danke schon mal im vorraus

    Andi



  • soll das unter einem der fetten betriebssysteme laufen?
    wenn ja, die haben so'nen mechanismus schon eingebaut.
    🙂



  • Das ganz soll unter Linux laufen



  • Andi123 schrieb:

    Das ganz soll unter Linux laufen

    linux macht doch auch paging/swapping oder so. probiers doch mal aus.
    🙂



  • Hab ich schon...es kommt die Meldung

    Segmentation fault (core dumped)

    Bei einer kleineren Datei ca. 700 000 Zeilen funktioniert es wunderbar



  • mal nur son Gedanke.

    Also Du willst ne riesige Datei in de Speicher laden und dann vom Speicher aus wieder auf Festplatte auslagern um dann darauf zuzugreifen...

    Warum nicht gleich auf der Platte arbeiten? Virtueller Speicher (aka Auslagerungsdatei) ist auch nicht schneller weil hier die Festplatte der limitierende Faktor ist.

    Ein entsprechend cleveres partielles Zugreifen auf Teile der Datei direkt könnte sogar erheblich performanter sein.

    Wie gesagt, nur son Gedanke...



  • Aber ich benötige alle Daten innerhalb der Textdatei in einem 2D Array, da ich diese Daten für die weitere Prozessierung beötige.

    Die Frage ist nur wie ich genugend Speicher für den 2 Dimensionalen Array bekomme.

    Oder hab ich grad einen Gedanken Fehler und das ganze lässt sich auch einacher lösen...



  • du könntest theoretisch auch eine Datei als 2d array betrachten. Immerhin ist das:

    (angenommen arraybreite = 10)

    a[5][2]

    das gleiche wie das

    a[5+2*10]

    Du kannst also die x/y-Koordinate in die Position des Filecursors umrechnen und dann mittels Seek anspringen.



  • jepp du interpretierst die datei als array..

    mach ne struktur mit den nötigen variablen welche jeweils einen datensatz bzw. eine zeile deines Array spiegelt. über ne funktion lies dann zeile für zeile in den strukt und verarbeitset das ganze...

    Wenn du allerdings nicht nur das array zum lesen willst, sonder auch zum schreiben wird er schwieriger..



  • Danke für die Hinweise, ich werd mich mal an die Arbeit machen.

    falls jemandem noch etwas dazu einfällt, kann er es gerne posten.

    Mfg

    Andi



  • gibt es nicht auch unter linux memory-mapping und dateien?
    Also wie MapViewOfFile... und schon kann man den inhalt der datei
    bequem über pointer ansprechen, obwohl er nicht im speicher ist.



  • Andi123 schrieb:

    falls jemandem noch etwas dazu einfällt, kann er es gerne posten.

    nimm 'memory-mapped files'. geht in linux bestimmt auch.
    🙂



  • man: mmap. Ist zwar kein Standard C mehr, aber in diesem Fall wohl grad egal.



  • Sollten 5mio doubles nicht "nur" 40Mb sein?

    Wenn da kein Denkfehler drin ist, liegt dein Problem wohl eher da, daß du diese 40 Mb nicht in einem Stück zur Verfügung hast. Versuch die doch irgendwie aufzuspalten, oder verwende verkettete Listen. Da ist der Gesamtspeicherbedarf zwar höher, aber er nimmt sich jede noch so kleine Lücke, wo ein einzelnes Element reinpaßt.



  • Nagila Hawa schrieb:

    Wenn da kein Denkfehler drin ist, liegt dein Problem wohl eher da, daß du diese 40 Mb nicht in einem Stück zur Verfügung hast. Versuch die doch irgendwie aufzuspalten, oder verwende verkettete Listen. Da ist der Gesamtspeicherbedarf zwar höher, aber er nimmt sich jede noch so kleine Lücke, wo ein einzelnes Element reinpaßt.

    Der Denkfehler liegt darin, daß malloc() ein primitiver Hund ist und nicht wirklich daran denkt, Lücken zu stopfen 😞 .
    Heißt, für sich genommen könnte man die Funktion so für sich ins Laufen bekommen, wenn aber andere auch mit malloc()/free() spielen, fragmentiert der Speicher mitunter so unglücklich, daß malloc() irgendwann NULL zurückgibt 👎 Davon abgesehen ist malloc() nicht wirklich schnell.

    Was mich wundert ist, daß Linux die lächerlichen 40 MB nicht hergeben mag, welche Hardware steht denn zur Verfügung?

    Ansonsten fällt mir wirklich nur eine dateibasierte Lösung ein, die wär' dann leichter abwärts skalierbar 🙄



  • Deswegen meine ich ja, daß das System sicher 40 Mb zur Verfügung stellen kann, aber eben nicht am Stück. Damit ein Array funktioniert, man auf alle Elemente zugreifen kann und keins verloren geht, müssen eben alle 5mio Elemente nebeneinander im Speicher liegen. Bei einer Liste bräuchte zwar jedes Element zusätzlich einen Zeiger, dafür können sich die Elemente frei im Speicher verteilen, da ist auch Fragmentierung kein großes Problem.



  • An pointercrash:

    Ich hätte mal eine Frage zu malloc().
    Was hat eigentlich malloc mit Speicherfragmentierung zu tun ? Denn ich dachte das malloc auf systeminterne Befehle des Betriebssystems zurückgreift um den Speicher zu reservieren. Ähnlich macht es nämlich auch printf, welche im Assembler-Code einfach eine Interrupt-Routine aufruft. Summa sumarum dürfte nur das Betriebssystem für die Reserverierung von Speicher verantwortlich sein und nicht malloc(). Deswegen dürfte Speicherfragmentierung und Schnelligkeit nur eine Frage des Betriebssystems sein.

    Übrigens, um mal noch auf das Hauptproblem zu kommen. Muss man dann eigentlich den kompletten Datensatz im RAM haben ? Genügt es vielleicht nicht, wenn nur 1 oder 2 MB an Daten im RAM sind. Wenn man dann diese bearbeitet hat, könnte man einfach die alten Daten mit neu gelesenen Daten überschreiben.



  • Bitte ein Bit schrieb:

    Was hat eigentlich malloc mit Speicherfragmentierung zu tun ? Denn ich dachte das malloc auf systeminterne Befehle des Betriebssystems zurückgreift um den Speicher zu reservieren.

    der 'heap' ist eine mini-speicherverwaltung für kleine blöcke mit byte-auflösung. wenn mans damit übertreibt, kann's schon fragmentieren. das OS ist für grössere happen zuständig (windoofs: VirtualAlloc, unix: sbrk), in der grössenordnung von etwa 4kB schritten, glaub ich.

    Bitte ein Bit schrieb:

    Ähnlich macht es nämlich auch printf, welche im Assembler-Code einfach eine Interrupt-Routine aufruft.

    printf ruft 'ne interrupt-routine auf? also nö, das wäre mir neu.
    🙂



  • Bitte ein Bit schrieb:

    Was hat eigentlich malloc mit Speicherfragmentierung zu tun ?

    OK, nimm' mal den denkbar schlechtesten Fall an: Du nimmst Dir per malloc in einer doppelt verketteten Liste elementweise den Speicher, bis malloc NULL zurückgibt. Aha, Speicher voll. Machen wir halt welchen frei und löschen jedes zweite Element aus der Liste mittels free (natürlich vergessen wir dabei nicht, die Verkettung zu aktualisieren 👍 ) und fordern anschließend per malloc Speicher an, der deutlich größer als ein Listenelement ist, an.
    Mit großer Wahrscheinlichkeit kriegen wir dann wieder NULL zurück 😞 , weil free nur Speicher als frei deklariert, aber nicht aufräumt. Wenn malloc den Speicher nicht am Stück vorfindet, sieht es ihn nicht.
    Will man sowas, bräuchte man z.B. eine Smartheap- Lib, die aber nicht Bestandteil des Standards ist.

    Bitte ein Bit schrieb:

    Denn ich dachte das malloc auf systeminterne Befehle des Betriebssystems zurückgreift um den Speicher zu reservieren.Summa sumarum dürfte nur das Betriebssystem für die Reserverierung von Speicher verantwortlich sein und nicht malloc(). Deswegen dürfte Speicherfragmentierung und Schnelligkeit nur eine Frage des Betriebssystems sein.

    Ist eine pure Implementationsfrage der stdlib. Wenn ein Betriebssystem da ist, wird es um Speicher angebettelt. Das OS entscheidet dann, ob malloc den kriegt oder nicht. Ist kein OS da, wird der Heap direkt in den physikalischen Speicher geschrieben, bis der alle ist. In keinem Fall kann verhindert werden, daß innerhalb des reservierten Speichers malloc/realloc/free die Landschaft ziemlich vergratteln können. 😮
    Ein bißchen was kann kann ein OS zwar retten, indem es Speicher seitenweise verwaltet und für die Applikation logisch zusammenhängenden Adreßraum anbietet, aber das grundlegende Problem innerhalb des Applikationsspeichers kann es nicht beseitigen. Den Effekt könntest Du selbst kennen, wenn Du einen PC lange Zeit unter Belastung laufen hast, auch mit Applikationen ohne memory leak. Mit der Zeit schwindet der freie Speicher. Wenn sich Fragmentierung und Restspeicher die Waage halten, ist's OK, dann merkst Du nichts davon, aber wenn das Ding anfängt zu swappen, weißt Du, was Sache ist.

    Bitte ein Bit schrieb:

    Muss man dann eigentlich den kompletten Datensatz im RAM haben ? ... Wenn man dann diese bearbeitet hat, könnte man einfach die alten Daten mit neu gelesenen Daten überschreiben.

    Soweit waren wir auch schon länger. Kommt drauf an, was der Frager mit den Daten vorhat. Eine Matrizenmultiplikation würde so zur Schnarchnummer. 😉


Log in to reply