DOS/4G

Tenberry Home

Consulting Services

Order DOS/4G

DOS/4G FAQ

Release Notes

DPMI Spec

* * *

DOS/4GW

DOS/4GW Pro

DOS/4G
for Watcom

DOS/16M

DOS/4G and DOS/4GW FAQ:
Performance


[Previous Section] * [Index of FAQ] * [Next Section]
  1. Will my application run faster if I upgrade DOS/4GW from version 1.97 to 2.01?
  2. Will my application run faster if I upgrade from DOS/4GW version 1.97 to DOS/4G for Watcom or full DOS/4G?
  3. What impact does running in protected mode have on my program?
  4. Assuming the machines are of equal speed (MHz), will DOS/4GW run faster on a PPro or a normal Pentium?
  5. I'm worried about the time spent switching between modes.
    Can I do all my execution in protected mode and eliminate switching to real mode?
  6. What is the fastest way to handle an interrupt?
  7. Can I reduce mode switching by using a particular compiler?
  8. Do calls to the standard C library cause mode switches?

1. Will my application run faster if I upgrade DOS/4GW from version 1.97 to 2.01?

No, probably not.

The changes between 1.97 and 2.01 are mostly bug fixes and compatibility improvements.


2. Will my application run faster if I upgrade from DOS/4GW version 1.97 to DOS/4G for Watcom or full DOS/4G?

Not directly.

The main difference between DOS/4GW and DOS/4G is increased functionality.

However, you can allocate more memory with DOS/4G and DOS/4G for Watcom, so if having larger buffers or arrays will help your simulation program run faster, then you may see improved performance.


3. What impact does running in protected mode have on my program?

There are several reasons why your program can run slower in protected mode:

  • Each time a segment register is loaded, the hardware performs checking on the selector to make sure it's valid.

  • Each call to DOS requires a switch to real mode and another switch back to protected mode.

  • Some compilers' memory management library functions, designed to work well with a few hundred KB, perform poorly when they have megabytes to manage.

  • The hardware on your computer may not live up to performance levels that the manufacturer implies.

There are several things you can do to improve performance:

Make fewer mode switches.

To reduce the number of mode switches in your program, look for the places in your code where you signal the same interrupt or DOS function call repeatedly. Try to pass larger amounts of information for each call, in order to reduce the number of calls, therefore the number of switches to real mode. For example, if your program sends output to the screen a character at a time, you can save mode switches by sending output a line at a time.

Some older C compilers have their printf function make a DOS call for each character of output, leading to a noticeable delay in filling the screen with text. One of several ways to reduce the switching overhead, when you use one of these compilers, would be to use sprintf to create an entire line (or screen) of formatted output, and then call fputs to do the output (eliminating all but one switch).

The Tenberry kernel does some optimization to reduce the number of mode switches. For example, if you have a tight loop that continually calls DOS function 2Ch to request the time, the kernel doesn't send each call to real mode. Instead, it tests to see if the timer has ticked since the program last called DOS function 2Ch. If not, it returns the same date and time that DOS returned from the last call.

Load segment registers less often.

Some important instructions run more slowly in protected mode than in real mode. In particular, any instruction that loads a segment register has to access the descriptor table. These instructions are: LDS, LES, MOV segreg, INT, and the intersegment CALL, JMP, and RET instructions. Use a compiler that makes the best use of these instructions and limit the use of these instructions in your own assembly code.

Don't use the BIOS for screen output. Instead, write directly to video RAM.

Using the BIOS for screen output can be slow because of mode switches. Instead, write directly to video RAM. If your program positions the cursor for each character output to the screen, consider changing your code to reposition the cursor only when necessary - that is, when waiting for mouse our keyboard input. This can make sluggish displays snappy again.

Put I/O buffers in low memory.

The Tenberry kernel transfers I/O buffers to and from extended memory through the transfer buffer. If an I/O buffer is in low memory, the kernel does not have to copy the data to or from extended memory. But since even the slowest AT-compatible machines can transfer data to and from extended memory at over 3MB per second, you would have to read and write massive amounts of data before you'd notice a difference in performance. Modern machines can typically read or write 10 to 20 MB per second.

The more important performance benefit of using low memory I/O buffers is that the kernel does not have to separate data into blocks that fit into the transfer buffer. If the transfer buffer is 8KB, and you write 40KB from extended memory to disk, the kernel performs the operation as 8KB writes. However, if the 40KB is in low memory, the kernel does not need to copy to the transfer buffer, and only one write occurs.

Handle interrupts in both modes.

If you have an interrupt-driven application (e.g., asynchronous communications with an interrupt per character), handle interrupts in both protected and real modes, since the switch time could well be as long as the time between interrupts.


4. Assuming the machines are of equal speed (MHz), will DOS/4GW run faster on a PPro or a normal Pentium?

Unfortunately, the answer is: it depends!

The PPro is quite a bit better at running 32-bit code than is the Pentium -- perhaps as much as 30-40% faster.

The Pentium is faster at running 16-bit code than is the PPro -- maybe 10-25%.

There are a few instructions for which the PPro is quite a bit slower than the Pentium -- particularly segment overrides (ES:, etc.) These will rarely, if ever occur in 32-bit code, but can be frequent in 16-bit code.

Optimizing specifically for the Pentium can get results closer to the PPro. General optimization or optimization for 486 or 386 will favor the PPro.

So, while running a DOS/4GW application:

  • The PPro will be a fair amount faster than a Pentium while running your 32-bit code.

  • The PPro will be somewhat slower while executing the code in the DOS/4GW extender, since there is a fair amount of 16-bit code in the extender.

  • And finally, a Pentium will do better if you tell the compiler to use Pentium-specific optimizations.


5. I'm worried about the time spent switching between modes.
Can I do all my execution in protected mode and eliminate switching to real mode?

Yes, if you do three things:

  • Not make any DOS or BIOS calls.

  • Not invoke any real-mode TSR's.

  • Have your own protected-mode handlers for all hardware interrupts.

Of course, it's hard to do all of the above for your whole program! You might be able to arrange it while your program was in a performance- critical section of your code.


6. What is the fastest way to handle an interrupt?

If you can limit the hardware interrupts to times when your program is running in protected mode, you can load the interrupt vector directly into the IDT.

This handling will not support interrupts which happen while the processor is executing in real mode. For this reason, our interrupt handling API provides an indirect layer to make interrupt handling largely algorithm compatible with real mode.

If you want to manipulate the IDT directly, you may -- at least when operating under plain DOS. If you are operating in a Windows DOS box, the IDT is generally not directly writeable.

If you do chose this technique, you should worry about what happens when your interrupt happens while the processor is operating in real mode.

Of course, all hardware interrupt handlers must be locked in the virtual memory. Otherwise, DOS could be executing, the hardware interrupt could occur, and the DOS extender might need to use DOS to perform virtual memory paging. Because DOS is not, in general, re-entrant, such a nested use of DOS will normally lead to a system crash or hang.


7. Can I reduce mode switching by using a particular compiler?

No. The compilers all have virtually the same performance, with regard to real-protected mode switches. The C/C++ run-time libraries are very similar in their implementation -- they have to be to maintain compatability.

The biggest thing you can do from a compiler point of view to reduce mode switches is to use buffered file I/O and to make the buffer sizes large.


8. Do calls to the standard C library cause mode switches?

First of all, the compilers' run-time libraries all execute in protected mode, so merely calling a library function will not cause a mode switch.

Note, however, that a library function may need to call DOS (or the BIOS) to perform it's function. For example, calling fputc() will cause a call to DOS to write a file (at least some of the time.)


[Previous Section] * [Index of FAQ] * [Next Section]
Last modified 2003.02.11. Your questions, comments, and feedback are welcome.