Das Large-Address-Aware-Flag

Donnerstag, 19. Februar 2009
 / von Axel
 

Der Markt befindet sich derzeit im Umbruch in das 64-Bit-Zeitalter, dennoch werden viele Programme – darunter vor allem Spiele – die daraus Vorteil schlagen könnten, weiterhin als reine 32-Bit-Anwendungen ausgeliefert.

Ein Grund dafür ist, dass es einen zusätzlichen Aufwand darstellt, darauf zu achten, dass eine Applikation auch wenn sie für 64-Bit kompiliert wird noch sauber läuft. Wurde dies während der Entwicklung nicht beachtet, wird dieser Aufwand oft gescheut. Zusätzlich müsste man aus Kompatibilitätsgründen heute stets beide Architekturen unterstützen und hätte damit einen erhöhten Supportaufwand.

Es gibt aber auch eine andere Maßnahme, um auch einem 32-Bit-Kompilat zumindest einen Teil der Vorteile eines 64-Bit-Betriebssystems zur Verfügung zu stellen. Dieser Mechanismus wird aber unverständlicherweise oft nicht beachtet. Dieses Techlet soll das sogenannte "Large-Address-Aware-Flag" und seine Eigenheiten deshalb einmal näher betrachten.

Das Large-Address-Aware-Flag

Moderne Betriebssysteme – darunter auch Windows XP/Vista – stellen jeder Applikation einen sogenannten virtuellen Adressraum zur Verfügung. Jede Anwendung sieht aus ihrem Blick den zugewiesenen Speicher in einem Stück, den sie mit linearer Adressierung ansprechen kann. Das Betriebssystem sorgt im Hintergrund mit Unterstützung des Protected Mode der CPU dafür, dass diese virtuellen Adressen auf echte, physikalische Speicheradressen abgebildet werden. Dieser Mechanismus ist komplex und soll hier nicht im Detail betrachtet werden.

Microsoft hat bei der Einführung von Windows NT den virtuellen Speicher in zwei Teile eingeteilt: 0-2 GiB ist der Applikation zugeteilt, während zwischen 2 und 4 GiB der Speicherraum des Windows-Kernels eingeblendet wird. Diese Maßnahme sorgt für Performancevorteile, wenn in den Kernel gewechselt werden muss, da dann kein Austauschen der virtuellen Speicherräume notwendig ist.

Später wurde aus Not nach mehr verwendbarem Speicherraum in speicherlastigen Applikationen für 32-Bit-Windows eine Kernel-Startoption eingeführt, die es erlaubt, 3 GiB virtuellen Adressraum zu definieren – dies hat aber oft Kompatibilitätsprobleme mit Treibern zur Folge, da diese nicht mehr genug Speicher im Kernel für sich beanspruchen können. Unter x64 Windows ist es zudem generell so, dass 32-Bit-Applikationen die vollen 4 GiB zur Verfügung gestellt bekommen.

Aus Kompatibilitätsgründen kann eine 32-Bit-Anwendung trotzdem normalerweise nur Adressen innerhalb der ersten 2 GiB des jeder Applikation zugeordneten virtuellen Adressraumes verwenden. Dies ist nötig, da Applikationen, die sich auf die strikte Einteilung des Speicherraums verlassen, teilweise das dadurch nicht signifikante hochwertigste Bit von Pointern (Zeiger auf Speicheradressen) als zusätzlichen Informationsspeicher verwenden. Fordert eine solche Applikation Speicher an, darf der zugewiesene Speicher nicht an Adressen über 2 GiB liegen, da sonst dieses Bit immer auf 1 stehen muss und somit bei Missbrauch der Applikation auf 0 gesetzt werden könnte, was einen sicheren Absturz bei Zugriffen darauf bedeuten würde.

32-Bit-Windows ohne LAA-Flag
32-Bit-Windows ohne LAA-Flag
64-Bit-Windows ohne LAA-Flag
64-Bit-Windows ohne LAA-Flag

Microsoft erlaubt es aber, durch das Large-Address-Aware-Flag Entwicklern dem Betriebssystem mitzuteilen, dass ihre Applikation dieses hochwertigste Bit nicht missbraucht, und somit auch Adressen über 2 GiB ohne weiteres verwenden kann. Dadurch ist es unter x64 Windows möglich, auch mit einer 32-Bit-Applikation volle 4 GiB virtuellen Adressraum zu verwenden – eine nicht zu unterschätzende Verdopplung:

Verwendung des Flags in bekannten Spielen

Einige Entwicklern ist dies offensichtlich bekannt. So ist z.B. bei Crysis und seinem Addon Warhead, Supreme Commander: Forged Alliance, Quake Wars: Enemy Territory, Neverwinter Nights 2 sowie Unreal Tournament 3 das LAA-Flag im Auslieferungszustand gesetzt. Crysis bieten vorbildlicherweise aber sowieso auch eine 64-Bit-Version.

Es gibt aber auch erstaunliche Negativbeispiele: So ist im jüngsten Fall das extrem speicherfressende GTA IV nicht entsprechend markiert und kann somit nur 2GiB virtuellen Adressraum und damit auch physikalischen RAM verwenden.

Man könnte nun meinen, dass ein manuelles Ändern des LAA-Flags keine Auswirkung auf die Applikation hat, da diese sowieso davon ausgehen muss, nicht mehr als 2GiB Adressraum zur Verfügung zu haben, da sonst Speicherallozierungen fehlschlagen würden. In der Praxis ergibt sich aber ein Performancevorteil bei Ladevorgängen, wenn das Flag gesetzt ist. Der Grund dafür ist wohl, dass der Speichermanager einfacher eine freie Speicheradresse finden kann, weil mehr Platz vorhanden ist und damit Fragmentierung vermieden wird. Aus diesem Grund ist es in diesem Zusammenhang auch ganz unerheblich, wieviel physikalischer RAM im System verbaut wird, da ja sowieso nicht mehr als 2 GiB Speicher angefordert wird.

Es könnte aber auch Fälle geben, in denen die Applikation beim System anfragt, wieviel Speicher sie maximal allozieren könnte. Dort wäre das LAA-Flag natürlich noch hilfreicher, da dann wirklich auch das doppelte an physikalischem Speicher verwendbar wäre. Das manuelle setzen kann z.B. durch den "CFF Explorer" erfolgen. Hier versteckt es sich unter "File Header" -> "Characteristics / Click here" -> "App can handle >2gb address space":

Dabei sollte beachtet werden, dass dies eine Veränderung des Programms darstellt, die vom Kopierschutz oder Cheaterkennungsroutinen bemerkt werden könnte. Es empfiehlt sich also nicht, dies bei Multiplayer-Spielen auszuprobieren, wenn man nicht sicher sein kann, dass man dadurch nicht des Schummelns verdächtigt wird. Außerdem verwenden manche Spiele Funktionen der Direct3D Hilfsbibliothek D3DX, die nicht mit vollen 32-Bit-Adressen zurecht kommen. Zudem existiert natürlich immer auch die Möglichkeit, dass das Spiel dazu wirklich von sich aus inkompatibel ist.

Fazit

Es ist erstaunlich, dass diese einfache Methode ohne gravierende Nachteile – bei moderner Softwareentwicklung – nicht viel breitflächiger eingesetzt wird. Wir würden uns wünschen, dass mehr Entwicklerstudios darauf aufmerksam werden, gerade wenn sie noch keine 64-Bit-Versionen zur Verfügung stellen wollen.

So lange kann man oft schon durch manuelles Setzen des Flags vielleicht einen Performancevorteil ergattern, wenn das Spiel mitmacht. Viel Spaß beim Ausprobieren!