std::deque real_max_size <<< max_size



  • Hi,

    ich bin auf der Suche nach einer Datenstruktur, welche eine sehr große Menge an Daten beinhalten kann (ca. 10 GB).
    Der std::vector steigt relativ schnell aus, da er ja den Speicher am Stück reservieren muss.

    Frage 1: Warum kann das aufgrund von Fragmentierung passieren? Bei einem 64 Bit System müsste doch immer "irgendwo" noch ein genügend großer virtuelle Speicherbereich frei sein.

    Danach habe ich mir die std::deque angeguckt. Diese verwaltet die Daten in Chunks.
    Doch auch die steigt bei der gleichen Größe (ca. 1 GB) aus.

    Frage 2: Wie kann das sein? Das System ist ein 64 Bit Windows 10 mit 12 GB Ram.
    Wenn ich manuell mehre Chunks reserviere, dann kann ich locker die 10 GB erreichen.

    #include <iostream>
    #include <vector>
    #include <deque>
    
    int main(int argc, char *argv[])
    {
        const std::size_t mb = 1000 * 1000;
        std::size_t i = 1;
        try {
            for (; i < 1000000; i *= 10) {
                std::deque<char> a;
                a.resize(i * mb);
                std::cout << a.size() / mb << " MB " << std::endl;
            }
        } catch(...) {
            std::cout << "bad alloc at " << i << " MB" << std::endl;
        }
    }
    


  • Du erzeugst auch ein 64 Bit Programm?

    max_size schrieb:

    Der std::vector steigt relativ schnell aus, da er ja den Speicher am Stück reservieren muss.

    Kann ich nicht nachvollziehen und halte ich für ein Gerücht.



  • std::deque hat zumindest in "meiner" Dinkumware und STLport Implementation einen riesigen Overhead pro Chunk. In den o.g. Implementationen ist jeder Chunk 16 Byte oder 1 Element (für Datentypen mit einer Größe > 16 Byte) groß, das ist für große Datenmengen völlig unbrauchbar.
    Leider kann man die Blockgröße für std::deque nicht festlegen und damit den Overhead reduzieren.



  • Unter Windows, d.h. im Visual Studio, muss man den Linker Parameter für große Addressen aktivieren, sonst kann/darf der Prozess maximal 2 oder 3 GB haben.



  • Skym0sh0 schrieb:

    Unter Windows, d.h. im Visual Studio, muss man den Linker Parameter für große Addressen aktivieren, sonst kann/darf der Prozess maximal 2 oder 3 GB haben.

    Du sprichst jetzt davon, einem 32Bit Programm mehr als 2 GB zu erlauben?



  • Versuch doch mal, einen std::vector mit 10GB reservierter Größe zu erzeugen.
    Unter 64bit sollte das bei den meisten Systemen gut funktionieren, da der virtuelle Speicher erst auf physikalischen Speicher abgebildet wird, wenn auf den Speicher auch zugegriffen wird.



  • Das Problem ist sicher dass er ne 32 Bit .exe baut.
    Da passt 1 GB ziemlich gut mit meinen Erfahrungen zusammen. Für nen 64 Bit Prozess wäre es lächerlich.


Log in to reply