[dll] inladen op non-base address

Pagina: 1
Acties:

  • demonite
  • Registratie: April 2000
  • Laatst online: 29-05 08:55

demonite

the way is up

Topicstarter
Het is mij opgevallen dat een aantal DLL's het VM nogal in groffe stukken hakt.
Dit komt omdat DLL's zo mogelijk ingeladen worden op hun "base-address"... Wat de logica hier achter is is me nog niet duidelijk overigens.

Zo wordt bv de QT dll een base address gegeven van 0x39D00000
En heeft de OpenGL32.dll een base address van 0x5ED00000

Aangezien je VM loopt van 0x0 tot 0x80000000 zijn bovenstaande addressen redelijk onhandig. Het verhindert het alloceren van grote stukken geheugen.

Nu kun je het base address wijzigen met een tool die "rebase.exe" heet en onderdeel is van de platform sdk. Maar ik voel er weinig voor een batch bestand te schrijven o.i.d. die op alle pc's dat truukje doet... Daarbij zijn die veranderingen permanent en dat lijkt me ook niet bepaald wenselijk.

Zou het niet mogelijk zijn om DLL's te laden op- of the verhuizen naar een bepaald address... ? Ik heb een flauw vermoeden dat dat ook mogelijk is met de platform SDK, met de functie RebaseImage()... maar als ik deze zo lees lijkt het ook erg permanent.

Aldus de SDK:
You can rebase an image to reduce the required load time for its DLLs. If an application can rely on a DLL being loaded at the desired load address, then the system loader does not have to relocate the image
Tja, wat is nou belangrijker ? De tijd die je applicatie nodig heeft om op te starten of het geheugen gebruik ? Nou zal dat eerste wel voor de meeste applicaties gelden, maar er zijn er toch ook die voor de laatste willen gaan.
Dat moet toch mogelijk zijn ?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21-08 12:02

.oisyn

Moderator Devschuur®

Demotivational Speaker

Aangezien je VM loopt van 0x0 tot 0x80000000 zijn bovenstaande addressen redelijk onhandig. Het verhindert het alloceren van grote stukken geheugen.
Onder winNT is het trouwens tot 0xc0000000. dat klopt trouwens niet, maar het is wel optioneel beschikbaar onder bepaalde NT OS'en.
En je beseft je wel dat dat 3 gigabyte aan addresseerbaar geheugen is? Als je al zoveel geheugen nodig hebt dan is het x86 platform eigenlijk niet echt de goede keus

En aangezien de base addressen nooit boven de 0x80000000 uitkomen heb je dus iig altijd wel 1 gb aan geheugen vrij om te alloceren :)

[ Voor 10% gewijzigd door .oisyn op 06-10-2003 16:59 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

demonite schreef op 06 October 2003 @ 16:50:
Tja, wat is nou belangrijker ? De tijd die je applicatie nodig heeft om op te starten of het geheugen gebruik ? Nou zal dat eerste wel voor de meeste applicaties gelden, maar er zijn er toch ook die voor de laatste willen gaan.
Dat moet toch mogelijk zijn ?
Het geheugengebruik blijft gelijk, of je ze nou na elkaar laadt of een eind van elkaar weg. Het is misschien wel beter ingedeeld, das waar (misschien bedoelde je dat met 'geheugengebruik', maar voor het geval dat).

Toch heb je meestal niet van die idioot grote stukken geheugen nodig.. Voor kleine stukjes heb je de Heap* functies, voor wat grotere (aantal MBs) de Virtual* functies en als je nog meer geheugen nodig hebt moet je je gaan afvragen of je niet beter files + een vorm van caching kunt gebruiken (tenzij je een enorme hoeveelheid geheugen hebt wordt waarschijnlijk toch een groot deel naar de harddisk gepaged).

Misschien heb je een volledig legitieme reden om zoveel geheugen te willen alloceren maar er zijn nog genoeg mensen die alles in het geheugen willen laden terwijl files zelfs een betere performance zouden geven.

www.madwizard.org


  • demonite
  • Registratie: April 2000
  • Laatst online: 29-05 08:55

demonite

the way is up

Topicstarter
het gaat om grote arrays (+/-500mb) die door fortran code wordt doorgerekend..
de allocatie gebeurd wel door c++, dus wellicht zijn die virtualalloc functies wel een optie idd.. Ik heb wel eens met de voorbeeld code uit de SDK zitten spelen, maar daar kreeg ik niet meer als 2 GB in totaal gealloceerd... (terwijl je volgens de SDK zelfs meer als 4 GB kunt gebruiken) Ik vraag me af wat er gebeurd als ik ipv dat testprogrammatje een programma gebruik waarbij de VM gefragmenteerd is door een zooitje DLL's

64bit is idd een beter platform, maar ik probeer gewoon het onderste uit de kan te halen zolang 64bit nog niet de standaard is voor windows.

Feit blijft dat het gewoon weird is om op zo'n manier je geheugen te fragmenteren..

.oisyn, ik krijg btw niet meer als 2GB gealloceerd hoor..

[ Voor 5% gewijzigd door demonite op 06-10-2003 20:54 ]


  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

PSDK:
Operating systems based on Microsoft® Windows NT® provide applications with a 4 GB virtual address space. The virtual address space is divided such that 2 GB is available to the application and the other 2 GB is available only to the system.
Bovenstaande link verwijst naar een artikel over 4GT RAM tuning, om 3GB aan geheugen mogelijk te maken. Weet niet of dat wel genoeg voor je is. Hier staat ook nog wat info en bekende problemen bij programma's draaiend met 4GT RAM tuning. Kan je echt niet om die grote arrays heen? Kan die fortran code het niet in delen verwerken ofzo?

www.madwizard.org


  • demonite
  • Registratie: April 2000
  • Laatst online: 29-05 08:55

demonite

the way is up

Topicstarter
heej, dat is een handige tip ! Ik vroeg me al af waar die /largeaddressaware optie op sloeg..
thnx very much, al is het geen antwoord op de vraag :)

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 00:12

Tomatoman

Fulltime prutser

Het base address van een DLL is bij de meeste compilers standaard ingesteld op $40000000. Zodra de DLL wordt geladen, zorgt Windows ervoor dat hij in een vrij stuk geheugen wordt geladen, dus op een ander base address dan het altijd al door een andere DLL bezette $40000000. Die mapping kost wat extra laadtijd. Daarom is het verstandig om als je zelf een DLL compileert, het base address te veranderen naar een stuk geheugen dat meestal vrij is.

Het base address moet je interpreteren als een gesuggereerd adres waarop de DLL wordt geladen. Is het geheugenblok al bezet, dan kiest Windows zelf een ander adres. Daar kun je niets aan veranderen.

Een goede grap mag vrienden kosten.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21-08 12:02

.oisyn

Moderator Devschuur®

Demotivational Speaker

tomatoman: je getalletjes kloppen niet helemaal, de default base voor een executable is 0x00400000, en die van een dll 0x10000000. Het verschilt natuurlijk per linker, maar dit is imho het meest voorkomend

[ Voor 25% gewijzigd door .oisyn op 06-10-2003 22:03 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 00:12

Tomatoman

Fulltime prutser

Even een check gedaan in Delphi en dit blijken daarin de standaardinstellingen:
Executable: 0x00400000
DLL: 0x00400000
* Tomatoman is gewend een beetje te overdrijven, in dit geval een factor 0x100 :)

Een goede grap mag vrienden kosten.


  • demonite
  • Registratie: April 2000
  • Laatst online: 29-05 08:55

demonite

the way is up

Topicstarter
Dat klopt idd, maar wanneer de DLL geladen wordt en het base address is nog vrij zal die DLL daar ingeladen worden...

Dus als er een aantal DLL's een "onhandig" base address hebben zullen die het geheugen fragmenteren..

Die instellingen van delphi zijn zo gek nog niet, in mijn geval dan. Door alles het zelfde base-address te geven laat je het windows uitzoeken hoe die rommel in het geheugen gemapped gaat worden. Of je dan op Windows wilt vertrouwen is weer een andere kwestie.

Maar anyway, een aantal Windows DLL's hebben al een raar base-address.. en daar wil ik de boel ook niet door laten verpesten.

  • Domokoen
  • Registratie: Januari 2003
  • Laatst online: 20-08 17:57
Het base address is een hint voor Windows waar die DLL standaard geladen wordt. Is dat adres al bezet door een andere, dan wordt deze gerelocate. Als je dan een tweede instantie laadt, kan deze de ander niet direct vinden (deze probeert weer het base address). Als je nu een uniek base address opgeeft, betekent dat dat extra instanties van de DLL meteen de bestaande instantie kunnen vinden en dat scheelt wat relocating e.d. als ik het wel heb.

Zo heb ik het in een boek gelezen :)

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 17:14
Rebasing doe je per .EXE plus bijbehorende DLLs. Je hoeft je dus geen zorgen te maken over het effect op andere applicaties, zolang je ervoor zorgt dat jouw applicatie zijn eigen set met DLLs heeft (in zelfde dir als .EXE). Op andere PCs zal je applicatie nog steeds in een eigen geheugenruimte komen, en de niet-systeem DLLs van je programma zijn daar even groot. De rebasing blijft daar dus gewoon werken. Wat je feitelijk doet is je memory image van je geladen programma tot een enkel blok samenvoegen.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • demonite
  • Registratie: April 2000
  • Laatst online: 29-05 08:55

demonite

the way is up

Topicstarter
Dat is inderdaad de bedoeling.. maar het lijkt me niet de bedoeling om systeem dll's mee te leveren die gerebased zijn.
En ik heb o.a. last van 3 systeem dll's die op een vreemde plek zitten.

Opengl32.dll 0x5ED00000
Shlwapi.dll 0x63180000
Glu32.dll 0x68b20000

En dan heb je nog wat andere systeem dll die van 0x71AA0000 tot 0x78000000 het geheugen fragmenteren... Maar dan kan ik nog mee leven omdat die ruimte wel opgevuld wordt door kleinere allocaties.

Ik kan er nix aan doen, ik blijf het echt het meest lompe verschijnsel van windows vinden.

[ Voor 12% gewijzigd door demonite op 08-10-2003 08:34 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21-08 12:02

.oisyn

Moderator Devschuur®

Demotivational Speaker

En als je het geheugen nou eens alloceert voordat de DLLs geladen worden? Desnoods doe je een VirtualAlloc om het geheugen alvast te reserveren.

Check ook eens de docs voor de /DELAYLOAD linker optie, dat scheelt je weer eigenhandige calls naar LoadLibrary en GetProcAddress :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1