Loading

The time it takes for a program to load is certainly part of the perception of speed. Nobody likes to wait 20 seconds or more for a program to load. While a user might load an application only once per session, a user might load a utility many times in a session, so load time is especially important for utilities.

Load time can be especially slow when a program uses many dynamic-link libraries (DLLs). Consider what Windows has to do to load such a program. First Windows loads the executable file itself, and then it goes through the list of dependent DLLs and loads one DLL at a time into the program's address space. Each DLL has a preferred base address from which all internal code and data has a relative offset. The DLL can load fairly quickly if it can load at its preferred address. However, if there is already something loaded at that address, Windows has to assign another base address and effectively relink the DLL to reset all the internal references to code and data. This process takes a far greater amount of time and results in the infamous LDR: Dll example.dll base 00600000 relocated due to collisions with c:\projects\example.exe message you see when you run the program from the debugger. Finally, once all the DLLs are loaded, Windows has to resolve all the external linkages by calling the GetProcAddress function for each imported DLL function.

One simple technique you can use to make loading faster is to ensure that your DLL files are easy for Windows to find. Windows (with the LoadLibrary function) searches directories in this order when looking for a DLL file:

  1. The directory from which the program loaded.
  2. The current directory.
  3. The Windows system directory.
  4. [Windows NT] The 16-bit Windows system directory.
  5. The Windows directory.
  6. The directories that are listed in the PATH environment variable.

Clearly, any DLL file found in the Windows directory or from the PATH environment variable is going to take longer to find than a DLL file in the program directory. Furthermore, note that the Designed for Microsoft Windows logo requirements recommend against installing your own DLLs in the Windows system directory. This prevents bloating the system directory with files that don't need to be there. It also avoids DLL version conflicts caused by DLLs shared between programs, at only a small cost of hard disk space. Once your DLL files are easy to find, much of the remaining loading activity can be eliminated by properly building your program. You can run the Rebase utility that comes with Visual C++ to process all your program's DLLs and set their base addresses so that they do not collide. Once the DLLs have base addresses that do not change when the DLL is loaded, you can then run the Bind utility on all the program's executable files, eliminating the need for the GetProcAddress function call by storing all the actual addresses of imported functions within the executable. There is no risk in doing this, since the binding process saves the timestamps of the DLLs to make sure the right file is used. If your program loads with a different DLL than the one that was bound, the linker uses the GetProcAddress technique instead. Note that you must always run Rebase before you run Bind.

TIP
Use the Rebase and Bind utilities to reduce your program's load time.

If you properly rebase and bind, even large programs that use many DLLs can load quickly. All executable files that come with Windows NT are bound.



Developing User Interfaces for Microsoft Windows
Developing User Interfaces for Microsoft Windows
ISBN: 0735605866
EAN: 2147483647
Year: 2005
Pages: 334

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net