new [] - bad alloc bei 2GB?



  • Kontrasubjekt schrieb:

    OS ist 64 bit, nur das Programm ist 32. 😕

    Gibt es mögliche Lösungen?

    Vorausgesetzt Du links mit vc++ linker :

    The /LARGEADDRESSAWARE option tells the linker that the application can handle addresses larger than 2 gigabytes. By default, /LARGEADDRESSAWARE:NO is enabled if /LARGEADDRESSAWARE is not otherwise specified on the linker line.



  • Kontrasubjekt schrieb:

    Ich verstehe noch nicht, wieso ich bei 32 bit x MB und bei 64 mehr bekommen soll, obwohl x noch unter 2GB liegt . Bei besagten 1.95GB existiert weder einen Konflikt mit der 2GB Grenze noch mit dem maximalen Adressraum für 32bit.
    Wie bekommen andere 32bit Programme so viel Speicher?

    Wie kommst du darauf dass sie das tun?
    Worum geht's dir eigentlich überhaupt?
    Die /LARGEADDRESSAWARE Option wurde vorgeschlagen, 64 Bit wurde vorgeschlagen...
    Was willst du jetzt noch wissen?

    Zieh dir vielleicht mal das Tool "VMMap" von Sysinternals, und guck dir damit den Adressraum deines Prozesses an. Dann siehst du ganz genau was wo überall belegt ist:
    http://technet.microsoft.com/en-us/sysinternals/dd535533.aspx



  • unskilled schrieb:

    Kontrasubjekt schrieb:

    SeppJ schrieb:

    Du verätst uns, wieso du glaubst, lowlevel arrays zu brauchen und wir sagen dir, wieso du sie nicht brauchst 😉

    Weil sie schneller sind als deque.

    kommt drauf an...
    so bald du punkte löschst, die nicht am ende sind oder nicht nur am ende hinzufügen möchtest, ist deque 100%ig schneller...

    bb

    Bist du da sicher? std::deque wird doch letztlich auch nur mit memmove, memcpy und Konsorten arbeiten. Und wieso sollte diese Implementation schneller arbeiten als was Eigenes (wenn man sich beim Programmieren nicht total blöd anstellt natürlich)? Ich lasse mich gerne eines Besseren belehren, aber ich bin da erstmal skeptisch.



  • hustbaer schrieb:

    Die /LARGEADDRESSAWARE Option wurde vorgeschlagen, 64 Bit wurde vorgeschlagen...
    Was willst du jetzt noch wissen?

    Ich möchte wissen welches Problem dem bad_alloc zugrundeliegt. Das habe ich doch geschrieben.
    Vermutet habe ich, dass der RAM fragmentiert ist und das sagen auch andere, nur frage ich mich wie ich meinen Speicher dennoch zusammentragen kann. Komme ich nicht drum herum 1.9 GB in 100MB stückchen anzufordern, oder gibt es andere Möglichkeiten?
    Basierend auf dem 64 bit Vorschlag möchte ich wissen, welchen unterschied eine 64 bit Applikation macht obwohl weder der 32bit Adressraum noch der 2GB Raum überschritten wurde.
    Large adress aware kann ich benutzen sobald ich über 2GB brauche. Es hat aber noch nichts mit dem aktuellen Problem zu tun, da ich nicht bei soviel bin.

    Worum geht's dir eigentlich überhaupt?

    Sicherstellen, dass ich genügend Speicher bekomme.

    Zieh dir vielleicht mal das Tool "VMMap" von Sysinternals, und guck dir damit den Adressraum deines Prozesses an. Dann siehst du ganz genau was wo überall belegt ist:
    http://technet.microsoft.com/en-us/sysinternals/dd535533.aspx

    Ich gucks mir mal an, danke.



  • Brauchst du denn wirklich Random Access?



  • Mit so einem Mini-Progrämmchen kann man ja ganz schön rausbekommen, wieviel Speicher man am Stück kriegt.

    int balloc=1024*1024*1024*2;
    	char *arr=0;
    	while(!arr) {
    		balloc-=1024*1024;
    		arr=(char*)realloc(arr,balloc);
    	}
    	printf("allocated: %d Bytes (%.2f MB)\n",balloc,balloc/1024./1024.);
    

    Bei mir sind's im Moment genau 1450 MB (XP x64, 8 GB RAM, 32-Bit-Anwendung). Und bei euch?



  • _matze schrieb:

    Bei mir sind's im Moment genau 1450 MB (XP x64, 8 GB RAM, 32-Bit-Anwendung). Und bei euch?

    1212MB (XP32, 2GB Ram, keine Auslagerungsdatei)
    1598MB (XP32, 2GB Ram, Auslagerungsdatei)
    1619MB, wenn ich im BIOS-Setup die shared memory ranges runterschraube.

    Ubrigens

    int mb=0;
        while(malloc(1024*1024)) {
        	++mb;
    			printf("allocated: %d MB\n",mb);
        }
    

    gibt weniger MB.



  • knivil schrieb:

    Brauchst du denn wirklich Random Access?

    Jo.



  • Ins Nirwana zu allozieren gehört sich aber nicht, volkard (das darf man höchstens mit dem bcc, dem Buddha-C-Compiler).



  • Mit LAA-Flag komme ich auf 2047 MB (vorher 1450).



  • ohne LAA und mit Auslagerungsdatei unter 32Bit-WinXP mit 2GB RAM:

    1987 MB

    Edit: 32 Bit-Anwendung, IDE MSVC++ 6.0 !! 😃 -> alte Besen kehren gut ^^



  • Kontrasubjekt schrieb:

    hustbaer schrieb:

    Die /LARGEADDRESSAWARE Option wurde vorgeschlagen, 64 Bit wurde vorgeschlagen...
    Was willst du jetzt noch wissen?

    Ich möchte wissen welches Problem dem bad_alloc zugrundeliegt. Das habe ich doch geschrieben.

    Das wurde doch schon beantwortet: es ist zu wenig zusammenhängender Adressraum vorhanden. Und ja, das nennt man "Fragmentierung".
    Wenn bloss ein einzelnen Byte, genau in der Mitte des Adressraums belegt ist, hast du bereits keine Chance mehr, mehr als 1GB am Stück zu bekommen.

    Nur weil das OS dem Prozess 2GB gibt, kannst du doch nicht davon ausgehen, dass nach geladenen DLLs, nach Anfordern von sonstigem Speicher, einblenden von Ranges zur Kommunikation mit den Kernel etc. auch nur annähernd 2GB übrig bleiben. Und die dann noch ab Stück.

    Deine Annahme "2GB Adressraum, daher kann ich auch 2GB anfordern" ist einfach total falsch. Vollkommen. Mehr falsch geht nicht.

    Komme ich nicht drum herum 1.9 GB in 100MB stückchen anzufordern, oder gibt es andere Möglichkeiten?

    Wurde doch schon ca. 100x erwähnt: 64 Bit und LAA 😕

    Large adress aware kann ich benutzen sobald ich über 2GB brauche. Es hat aber noch nichts mit dem aktuellen Problem zu tun, da ich nicht bei soviel bin.

    Dein Problem ist, dass du uns nicht glaubst. Natürlich bist du schon soweit. Mach es einfach. Ich verstehe nicht wieso du dich gegen eine Lösung streubst, die funktioniert, nur weil du der Meinung bist, dass du es "nicht brauchst".

    Sollte die Verwendung von LAA bzw. einem 64 Bit Prozess ein Problem darstellen, dann wäre es vermutlich günstig, wenn du uns darauf hinweist, und auch verrätst WAS du denn da genau für ein Problem siehst.

    Ansonsten, wie gesagt, bitte mach es einfach.



  • Kontrasubjekt schrieb:

    knivil schrieb:

    Brauchst du denn wirklich Random Access?

    Jo.

    Dann kaufe dir einfach mehr Speicher. Erstelle eine 64Bit-Anwendung. Die Fragmentierung wird dir sowieso alles kaputt machen, wenn du so knapp an der Grenze bist.



  • @hustbaer: Du scheinst da etwas misszuverstehen. Ich habe nicht die Annahme gemacht, ich könne 2GB bekommen weil 2GB frei sind. Allerdings hab ich die Bibliotheken nicht zu den 1.95 GB mitgezählt. Vielleicht haben die den Unterschied gemacht.

    Ich möchte eine Möglichkeit finden, mit oder ohne LAA mehr prozent des verfügbaren Raums zu bekommen. Denn wie ich das verstanden hab ändert LAA nichts an der Fragmentierung. Ziel ist möglichst zu garantieren, dass Verfügbarer Speicher minus einige 100MB sicherheit bereitgestellt werden. Verstehst du nun?

    Meine Frage, was der 64 bit Modus mit der Speicheranforderung zu tun hat, ist übrigens eine reine Verständnisfrage.

    Sollte die Verwendung von LAA bzw. einem 64 Bit Prozess ein Problem darstellen, dann wäre es vermutlich günstig, wenn du uns darauf hinweist, und auch verrätst WAS du denn da genau für ein Problem siehst.

    Ich möchte das Programm auch auf 32 bit laufen lassen können. @LAA siehe oben.



  • @Kontrasubjekt: OK, ich glaube ich verstehe jetzt was du meinst/willst 🙂

    Allerdings hab ich die Bibliotheken nicht zu den 1.95 GB mitgezählt. Vielleicht haben die den Unterschied gemacht.

    Sind wie gesagt nicht nur die DLLs, sondern auch noch andere Dinge.
    Guck dir einfach mal einen Prozess im VMMap an, dann siehst du recht gut was da wo liegt. Hier nochmal der Link:
    http://technet.microsoft.com/en-us/sysinternals/dd535533.aspx

    Ich möchte eine Möglichkeit finden, mit oder ohne LAA mehr prozent des verfügbaren Raums zu bekommen. Denn wie ich das verstanden hab ändert LAA nichts an der Fragmentierung.

    Das wird vermutlich so sein, ja.

    Ziel ist möglichst zu garantieren, dass Verfügbarer Speicher minus einige 100MB sicherheit bereitgestellt werden. Verstehst du nun?

    Jopp.
    Dann bleibt dir aber vermutlich nichts anderes übrig, als kleine Stücke anzufordern.
    Vielleicht in einer eigenen deque-ähnlichen Datenstruktur. ca. so:

    static const size_t PageSize = 64 * 1024;
    
    struct Page
    {
        int Elements[PageSize];
    };
    
    struct MyArray
    {
        std::vector<Page*> m_pages;
    
        int& operator[](size_t n)
        {
            return m_pages[n / PageSize]->Elements[n % PageSize];
        }
    };
    

    Der Zugriff sollte so relativ schnell sein. Wenn du PageSize als Zweierpotenz definierst, dann wird die Divison zu einem Shift und der Modulo zu einem AND. Also beides sehr billige Operationen.

    Ist jetzt natürlich bloss ein Beispiel. Ich weiss ja nicht welche Operationen (ausser Random-Access) du auf der Datenstruktur noch brauchst, und welche davon wirklich schnell sein müssen.

    Grund: selbst wenn du es auf deinem System hinbekommst, dass z.B. 1,7GB am Stück frei sind, muss das nicht auf allen Systemen funktionieren. Es könnten z.B. Programme installiert sein die DLLs in sämtliche Prozesse injecten. Wenn eine solche DLL dann "blöd liegt", kann es sein, dass du auf einmal statt 1,7GB bloss noch 1,3GB am Stück bekommst. Sehr häufig wird es vermutlich nicht vorkommen, aber wie gesagt: verlassen kannst du dich nicht darauf.
    Grundsätzlich: je näher du an die Grenze gehst, desto höher sind die Chancen, dass du auf anderen Systemen Probleme haben wirst.

    Und das LAA Bit würde ich auf jeden Fall setzen. Wenns nix bringt, kanns kaum was schaden 🙂



  • Willst du uns mal sagen was dein Programm mal können soll, außer viel Speicher brauchen. I wette, dass das was du vor hast auch mit viel weniger Speicher geht.


  • Mod

    wetten dass schrieb:

    Willst du uns mal sagen was dein Programm mal können soll, außer viel Speicher brauchen. I wette, dass das was du vor hast auch mit viel weniger Speicher geht.

    Er möchte einen Software Renderer mit GPU Beschleunigung schreiben, so paradox dies auch klingen mag:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-249954-and-highlight-is-.html



  • Kontrasubjekt schrieb:

    Ich verstehe noch nicht, wieso ich bei 32 bit x MB und bei 64 mehr bekommen soll, obwohl x noch unter 2GB liegt.

    Dein Programm alloziert garantiert anderweitig schon Speicher, und das ist bei 64Bit dann kein Problem mehr, weil der gesamte Adreßraum deutlich größer ist. Also, was soll der Schmarrn, mach eine 64Bit Applikation draus. Alles andere ist nur Frickelei.



  • hustbaer schrieb:

    Der Zugriff sollte so relativ schnell sein. Wenn du PageSize als Zweierpotenz definierst, dann wird die Divison zu einem Shift und der Modulo zu einem AND. Also beides sehr billige Operationen.

    Ist jetzt natürlich bloss ein Beispiel. Ich weiss ja nicht welche Operationen (ausser Random-Access) du auf der Datenstruktur noch brauchst, und welche davon wirklich schnell sein müssen.

    Leider alle. Zweierpotenz werd ich berücksichtigen, gute Idee. 👍

    Ich schätze ich habe bessere Chancen wenn ich vorher eine Ram defrag durchführen lasse, oder?



  • ~john schrieb:

    Also, was soll der Schmarrn, mach eine 64Bit Applikation draus. Alles andere ist nur Frickelei.

    Das widerspricht ja der Vorgabe, dass die Anwendung auch unter x86 laufen soll. Andererseits widerspricht dem der Wunsch, 2 GB am Stück zu allozieren... toll, jetzt bin ich verwirrt... 😉


Anmelden zum Antworten