Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

21

06.06.2014, 14:14

Du kannst VirtualAlloc eine Adresse übergeben, an der du reservieren möchtest. Ganz naiv würdest du also in 1-MiB-Schritten über den Adressraum gehen, bei jedem Schritt via VirtualQuery prüfen, ob der Block dort allokiert ist, und falls nicht, VirtualAlloc mit dieser Adresse aufrufen. Das kannst du dann optimieren indem du Liste über die Blöcke führst.
Was sprach gegen diese Lösung?

Und einen Fallback-Algorithmus für aligned_malloc mit Riesenalignment gibt es nicht weil nur eines aus 100.000 Programmen Alignment > 256 benutzt. Deins würde dann schneller werden, aber 99.999 andere langsamer. Wäre ein schlechter Deal.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Krishty« (06.06.2014, 14:33)


Evrey

Treue Seele

  • »Evrey« ist der Autor dieses Themas

Beiträge: 245

Beruf: Weltherrscher

  • Private Nachricht senden

22

06.06.2014, 14:49

Na ja... mir gefällt nicht, die Arbeit des Betriebssystems abnehmen zu müssen. Zunächst stellt sich die Frage, wo ich mit der Suche anfangen soll. Weiß Gott, wie hoch der Speicher-Verbrauch bis zur Allokation der ersten Arena ist. Dann müsste ich erst mit O(n) quer durch die Adressen testen, bis ich den ersten freien Block finde. Bei jeder neuen Arena könnte ich erstmal naiv testen, ob ich unmittelbar hinter der zuvor allokierten an Speicher komme, oder doch nochmals quer durch suchen muss. Arbeit, die das Betriebssystem wesentlich schneller erledigen könnte, da es bereits eine zuverlässige Buchführung der genutzten Pages bietet.

C-/C++-Quelltext

1
2
3
4
int main(int _argc, char** _argv) noexcept {
  asm volatile("lock cmpxchg8b %eax");
  return 0;
} // ::main
(Dieses kleine Biest vermochte einst x86-Prozessoren lahm zu legen.)

=> Und er blogt unter Hackish.Codes D:

23

06.06.2014, 14:58

Unter 32-Bit-Windows wären es schlimmstenfalls 32.768 Tests. Du kannst ja direkt am Anfang reservieren, wenn der Adressraum noch leer ist. Und wenn es richtig brutal sein muss, dann allokier einfach 2 MiB via VirtualAlloc, merk dir die Adresse; gib es wieder frei; und teste die auf 1 MiB ausgerichtete gemerkte Adresse zuerst (die Wahrscheinlichkeit, dass sie dir zwischendurch ein anderer Thread wegschnappt, ist winzig). Mess einfach mal aus wie langsam das wirklich ist.

In absoluter Not google nach Reverse Engineering von HeapAlloc, das ist ebenfalls eine Arena ein Pool und muss den Speicher ja auch irgendwoher VirtualAlloc'n.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Krishty« (06.06.2014, 15:04)


Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

24

06.06.2014, 15:22

Spricht etwas degegen einfach 2MB zu allokieren, einen Pointer auf eine 1MB Grenze zu schnappen und denn Rest wieder frei zu geben? Nach meinen Verständnis von Paging sollte das kein Problem sein und ich konnte jetzt gerade auf die schnelle auch nichts Windowsspezifisches finden, was dagegen spricht. Wenn doch, wäre das jetzt auch nicht extrem schlimm. Wenn eine Page nur reserviert und nicht committed ist, ist kein physikalischer Speicher zugeweisen. Wenn du eh mehr brauchst, könntest auch gleich 1GB damit allokieren und dann entsprechend aligned verwenden. Auf 32 Bit Betriebssystemen/Anwendungen solltest du nur nicht über 1GB gehen, sonst sprengt das den virtuellen Adressraum, wenn nur 2 - 3GB des Virtuellen vorhanden sind. Auf 64 Bit ist der Adressraum für so ziemlich jede sinnvolle und sinnfreie Größe ausreichend.

25

06.06.2014, 15:26

Er kann den Rest nicht wieder freigeben weil VirtualFree nur auf den kompletten Block (also die ganzen 2 MiB) auf einmal funktioniert. Er könnte den Überfluss höchstens decommitten, aber das würde ja nichts bewirken.

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

26

06.06.2014, 15:31

Aha. Ich habe es jetzt auch gefunden. "The entire range of pages originally reserved by the VirtualAlloc function must be released at the same time." Ist ja dumm. Dann halt in den unbenutzten Teil einfach nicht beschreiben und nicht committen wie bereits mit vorgeschlagen. Für weniger Verschnitt im virtuellen Adressraum am Besten gleich groß zuschlagen wie erläutert.

Evrey

Treue Seele

  • »Evrey« ist der Autor dieses Themas

Beiträge: 245

Beruf: Weltherrscher

  • Private Nachricht senden

27

06.06.2014, 20:05

Zitat

Und wenn es richtig brutal sein muss, dann allokier einfach 2 MiB via VirtualAlloc, merk dir die Adresse; gib es wieder frei; und teste die auf 1 MiB ausgerichtete gemerkte Adresse zuerst
Das wäre die wohl sinnvollste Alternative. Werde ich so umsetzen, danke.
(Darauf hätte ich auch kommen können... Manchmal ist man eben blind und doof.)

C-/C++-Quelltext

1
2
3
4
int main(int _argc, char** _argv) noexcept {
  asm volatile("lock cmpxchg8b %eax");
  return 0;
} // ::main
(Dieses kleine Biest vermochte einst x86-Prozessoren lahm zu legen.)

=> Und er blogt unter Hackish.Codes D:

Werbeanzeige