Initial conversion to markdown
This commit is contained in:
parent
a96a114403
commit
5e10794a24
362 changed files with 67353 additions and 0 deletions
139
03-08.md
Normal file
139
03-08.md
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
------------------------ --------------------------------- --------------------
|
||||
[Previous](03-07.html) [Table of Contents](index.html) [Next](03-09.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
Moreover, because it uses an undocumented feature, the timer-stop
|
||||
approach could conceivably cause erratic 8253 operation, which could in
|
||||
turn seriously affect your computer’s operation until the next reboot.
|
||||
In non-8253-compatible systems, I’ve observed not only wildly incorrect
|
||||
timing results, but also failure of a diskette drive to operate properly
|
||||
after the long-period Zen timer with **PS2** set to 0 has run, so be
|
||||
alert for signs of trouble if you do set **PS2** to 0.
|
||||
|
||||
Rebooting should clear up any timer-related problems of the sort
|
||||
described above. (This gives us another reason to reboot at the end of
|
||||
each code-timing session.) You should *immediately* reboot and set the
|
||||
**PS2** equate to 1 if you get erratic or obviously incorrect results
|
||||
with the long-period Zen timer when **PS2** is set to 0. If you want to
|
||||
set **PS2** to 0, it would be a good idea to time a few of the listings
|
||||
in this book with **PS2** set first to 1 and then to 0, to make sure
|
||||
that the results match. If they’re consistently different, you should
|
||||
set **PS2** to 1.
|
||||
|
||||
While the the non-PS/2 version is more dangerous than the PS/2 version,
|
||||
it also produces more accurate results when it does work. If you have a
|
||||
non-PS/2 PC-compatible computer, the choice between the two timing
|
||||
approaches is yours.
|
||||
|
||||
If you do leave the **PS2** equate at 1 in Listing 3.5, you should
|
||||
repeat each code-timing run several times before relying on the results
|
||||
to be accurate to more than 54 ms, since variations may result from the
|
||||
possible lack of synchronization between the timer 0 count and the BIOS
|
||||
time-of-day count. In fact, it’s a good idea to time code more than once
|
||||
no matter which version of the long-period Zen timer you’re using, since
|
||||
interrupts, which must be enabled in order for the long-period timer to
|
||||
work properly, may occur at any time and can alter execution time
|
||||
substantially.
|
||||
|
||||
Finally, please note that the *precision* Zen timer works perfectly well
|
||||
on both PS/2 and non-PS/2 computers. The PS/2 and 8253 considerations
|
||||
we’ve just discussed apply *only* to the longZen timer.
|
||||
|
||||
### Example Use of the Long-Period Zen Timer {#Heading14}
|
||||
|
||||
The long-period Zen timer has exactly the same calling interface as the
|
||||
precision Zen timer, and can be used in place of the precision Zen timer
|
||||
simply by linking it to the code to be timed in place of linking the
|
||||
precision timer code. Whenever the precision Zen timer informs you that
|
||||
the code being timed takes too long for the precision timer to handle,
|
||||
all you have to do is link in the long-period timer instead.
|
||||
|
||||
Listing 3.6 shows a test-bed program for the long-period Zen timer.
|
||||
While this program is similar to Listing 3.2, it’s worth noting that
|
||||
Listing 3.6 waits for a few seconds before calling **ZTimerOn**, thereby
|
||||
allowing any pending keyboard interrupts to be processed. Since
|
||||
interrupts must be left on in order to time periods longer than 54 ms,
|
||||
the interrupts generated by keystrokes (including the upstroke of the
|
||||
Enter key press that starts the program)—or any other interrupts, for
|
||||
that matter—could incorrectly inflate the time recorded by the
|
||||
long-period Zen timer. In light of this, resist the temptation to type
|
||||
ahead, move the mouse, or the like while the long-period Zen timer is
|
||||
timing.
|
||||
|
||||
**LISTING 3.6 LZTEST.ASM**
|
||||
|
||||
; Program to measure performance of code that takes longer than
|
||||
; 54 ms to execute. (LZTEST.ASM)
|
||||
;
|
||||
; Link with LZTIMER.ASM (Listing 3.5). LZTIME.BAT (Listing 3.7)
|
||||
; can be used to assemble and link both files. Code to be
|
||||
; measured must be in the file TESTCODE; Listing 3.8 shows
|
||||
; a sample file (LST3-8.ASM) which should be named TESTCODE.
|
||||
;
|
||||
; By Michael Abrash
|
||||
;
|
||||
mystack segment para stack ‘STACK’
|
||||
db 512 dup(?)
|
||||
mystack ends
|
||||
;
|
||||
Code segment para public ‘CODE’
|
||||
assume cs:Code, ds:Code
|
||||
extrn ZTimerOn:near, ZTimerOff:near, ZTimerReport:near
|
||||
Startproc near
|
||||
push cs
|
||||
pop ds ;point DS to the code segment,
|
||||
; so data as well as code can easily
|
||||
; be included in TESTCODE
|
||||
;
|
||||
; Delay for 6-7 seconds, to let the Enter keystroke that started the
|
||||
; program come back up.
|
||||
;
|
||||
mov ah,2ch
|
||||
int 21h ;get the current time
|
||||
mov bh,dh ;set the current time aside
|
||||
DelayLoop:
|
||||
mov ah,2ch
|
||||
push bx ;preserve start time
|
||||
int 21h ;get time
|
||||
pop bx ;retrieve start time
|
||||
cmp dh,bh ;is the new seconds count less than
|
||||
; the start seconds count?
|
||||
jnb CheckDelayTime ;no
|
||||
add dh,60 ;yes, a minute must have turned over,
|
||||
; so add one minute
|
||||
CheckDelayTime:
|
||||
sub dh,bh ;get time that’s passed
|
||||
cmp dh,7 ;has it been more than 6 seconds yet?
|
||||
jb DelayLoop ;not yet
|
||||
;
|
||||
include TESTCODE ;code to be measured, including calls
|
||||
; to ZTimerOn and ZTimerOff
|
||||
;
|
||||
; Display the results.
|
||||
;
|
||||
call ZTimerReport
|
||||
;
|
||||
; Terminate the program.
|
||||
;
|
||||
mov ah,4ch
|
||||
int 21h
|
||||
Start endp
|
||||
Code ends
|
||||
end Start
|
||||
|
||||
As with the precision Zen timer, the program in Listing 3.6 is used by
|
||||
naming the file containing the code to be timed TESTCODE, then
|
||||
assembling both Listing 3.6 and Listing 3.5 with MASM or TASM and
|
||||
linking the two files together by way of the Microsoft or Borland
|
||||
linker. Listing 3.7 shows a batch file, named LZTIME.BAT, which does all
|
||||
of the above, generating and running the executable file LZTEST.EXE.
|
||||
LZTIME.BAT assumes that the file LZTIMER.ASM contains Listing 3.5 and
|
||||
the file LZTEST.ASM contains Listing 3.6.
|
||||
|
||||
------------------------ --------------------------------- --------------------
|
||||
[Previous](03-07.html) [Table of Contents](index.html) [Next](03-09.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
* * * * *
|
||||
|
||||
Graphics Programming Black Book © 2001 Michael Abrash
|
||||
Loading…
Reference in a new issue