Initial conversion to markdown
This commit is contained in:
parent
a96a114403
commit
5e10794a24
362 changed files with 67353 additions and 0 deletions
171
03-05.md
Normal file
171
03-05.md
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
------------------------ --------------------------------- --------------------
|
||||
[Previous](03-04.html) [Table of Contents](index.html) [Next](03-06.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
### Notes on the Zen Timer {#Heading10}
|
||||
|
||||
The Zen timer subroutines are designed to be near-called from assembly
|
||||
language code running in the public segment **Code**. The Zen timer
|
||||
subroutines can, however, be called from any assembly or high-level
|
||||
language code that generates OBJ files that are compatible with the
|
||||
Microsoft linker, simply by modifying the segment that the timer code
|
||||
runs in to match the segment used by the code being timed, or by
|
||||
changing the Zen timer routines to far procedures and making far calls
|
||||
to the Zen timer code from the code being timed, as discussed at the end
|
||||
of this chapter. All three subroutines preserve all registers and all
|
||||
flags except the interrupt flag, so calls to these routines are
|
||||
transparent to the calling code.
|
||||
|
||||
If you do change the Zen timer routines to far procedures in order to
|
||||
call them from code running in another segment, be sure to make *all*
|
||||
the Zen timer routines far, including **ReferenceZTimerOn** and
|
||||
**ReferenceZTimerOff**. (You’ll have to put **FAR PTR** overrides on the
|
||||
calls from **ZTimerOff** to the latter two routines if you do make them
|
||||
far.) If the reference routines aren’t the same type—near or far—as the
|
||||
other routines, they won’t reflect the true overhead incurred by
|
||||
starting and stopping the Zen timer.
|
||||
|
||||
Please be aware that the inaccuracy that the Zen timer can introduce
|
||||
into the system clock time does not affect the accuracy of the
|
||||
performance measurements reported by the Zen timer itself. The 8253
|
||||
counts once every 838 ns, giving us a count resolution of about 1µs,
|
||||
although factors such as the prefetch queue (as discussed below),
|
||||
dynamic RAM refresh, and internal timing variations in the 8253 make it
|
||||
perhaps more accurate to describe the Zen timer as measuring code
|
||||
performance with an accuracy of better than 10µs. In fact, the Zen timer
|
||||
is actually most accurate in assessing code performance when timing
|
||||
intervals longer than about 100 µs. At any rate, we’re most interested
|
||||
in using the Zen timer to assess the relative performance of various
|
||||
code sequences—that is, using it to compare and tweak code—and the timer
|
||||
is more than accurate enough for that purpose.
|
||||
|
||||
The Zen timer works on all PC-compatible computers I’ve tested it on,
|
||||
including XTs, ATs, PS/2 computers, and 386, 486, and Pentium-based
|
||||
machines. Of course, I haven’t been able to test it on *all*
|
||||
PC-compatibles, but I don’t expect any problems; computers on which the
|
||||
Zen timer doesn’t run can’t truly be called “PC-compatible.”
|
||||
|
||||
On the other hand, there is certainly no guarantee that code performance
|
||||
as measured by the Zen timer will be the same on compatible computers as
|
||||
on genuine IBM machines, or that either absolute or relative code
|
||||
performance will be similar even on different IBM models; in fact, quite
|
||||
the opposite is true. For example, every PS/2 computer, even the
|
||||
relatively slow Model 30, executes code much faster than does a PC or
|
||||
XT. As another example, I set out to do the timings for my earlier book
|
||||
*Zen of Assembly Language* on an XTcomputer, only to find that the
|
||||
computer wasn’t quite IBM-compatible regarding code performance. The
|
||||
differences were minor, mind you, but my experience illustrates the risk
|
||||
of assuming that a specific make of computer will perform in a certain
|
||||
way without actually checking.
|
||||
|
||||
Not that this variation between models makes the Zen timer one whit less
|
||||
useful—quite the contrary. The Zen timer is an excellent tool for
|
||||
evaluating code performance over the entire spectrum of PC-compatible
|
||||
computers.
|
||||
|
||||
### A Sample Use of the Zen Timer {#Heading11}
|
||||
|
||||
Listing 3.2 shows a test-bed program for measuring code performance with
|
||||
the Zen timer. This program sets DS equal to CS (for reasons we’ll
|
||||
discuss shortly), includes the code to be measured from the file
|
||||
TESTCODE, and calls **ZTimerReport** to display the timing results.
|
||||
Consequently, the code being measured should be in the file TESTCODE,
|
||||
and should contain calls to **ZTimerOn** and **ZTimerOff** .
|
||||
|
||||
**LISTING 3.2 PZTEST.ASM**
|
||||
|
||||
; Program to measure performance of code that takes less than
|
||||
; 54 ms to execute. (PZTEST.ASM)
|
||||
;
|
||||
; Link with PZTIMER.ASM (Listing 3.1). PZTEST.BAT (Listing 3.4)
|
||||
; can be used to assemble and link both files. Code to be
|
||||
; measured must be in the file TESTCODE; Listing 3.3 shows
|
||||
; a sample TESTCODE file.
|
||||
;
|
||||
; By Michael Abrash
|
||||
;
|
||||
mystack segment para stack ‘STACK’
|
||||
db 512 dup(?)
|
||||
mystack ends
|
||||
;
|
||||
Code segment para public ‘CODE’
|
||||
assume cs:Code, ds:Code
|
||||
extrnZTimerOn:near, ZTimerOff:near, ZTimerReport:near
|
||||
Start proc near
|
||||
push cs
|
||||
pop ds ; set DS to point to the code segment,
|
||||
; so data as well as code can easily
|
||||
; be included in TESTCODE
|
||||
;
|
||||
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
|
||||
|
||||
Listing 3.3 shows some sample code to be timed. This listing measures
|
||||
the time required to execute 1,000 loads of AL from the memory variable
|
||||
**MemVar** . Note that Listing 3.3 calls **ZTimerOn** to start timing,
|
||||
performs 1,000 **MOV** instructions in a row, and calls **ZTimerOff** to
|
||||
end timing. When Listing 3.2 is named TESTCODE and included by Listing
|
||||
3.3, Listing 3.2 calls **ZTimerReport** to display the execution time
|
||||
after the code in Listing 3.3 has been run.
|
||||
|
||||
**LISTING 3.3 LST3-3.ASM**
|
||||
|
||||
; Test file;
|
||||
; Measures the performance of 1,000 loads of AL from
|
||||
; memory. (Use by renaming to TESTCODE, which is
|
||||
; included by PZTEST.ASM (Listing 3.2). PZTIME.BAT
|
||||
; (Listing 3.4) does this, along with all assembly
|
||||
; and linking.)
|
||||
;
|
||||
jmp Skip ;jump around defined data
|
||||
;
|
||||
MemVar db ?
|
||||
;
|
||||
Skip:
|
||||
;
|
||||
; Start timing.
|
||||
;
|
||||
call ZTimerOn
|
||||
;
|
||||
rept 1000
|
||||
mov al,[MemVar]
|
||||
endm
|
||||
;
|
||||
; Stop timing.
|
||||
;
|
||||
call ZTimerOff
|
||||
|
||||
It’s worth noting that Listing 3.3 begins by jumping around the memory
|
||||
variable **MemVar**. This approach lets us avoid reproducing Listing 3.2
|
||||
in its entirety for each code fragment we want to measure; by defining
|
||||
any needed data right in the code segment and jumping around that data,
|
||||
each listing becomes self-contained and can be plugged directly into
|
||||
Listing 3.2 as TESTCODE. Listing 3.2 sets DS equal to CS before doing
|
||||
anything else precisely so that data can be embedded in code fragments
|
||||
being timed. Note that only after the initial jump is performed in
|
||||
Listing 3.3 is the Zen timer started, since we don’t want to include the
|
||||
execution time of start-up code in the timing interval. That’s why the
|
||||
calls to **ZTimerOn** and **ZTimerOff** are in TESTCODE, not in
|
||||
PZTEST.ASM; this way, we have full control over which portion of
|
||||
TESTCODE is timed, and we can keep set-up code and the like out of the
|
||||
timing interval.
|
||||
|
||||
------------------------ --------------------------------- --------------------
|
||||
[Previous](03-04.html) [Table of Contents](index.html) [Next](03-06.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
* * * * *
|
||||
|
||||
Graphics Programming Black Book © 2001 Michael Abrash
|
||||
Loading…
Reference in a new issue