154 lines
9.8 KiB
HTML
154 lines
9.8 KiB
HTML
<HTML>
|
|
<HEAD>
|
|
<META name=vsisbn content="1576101746">
|
|
<META name=vstitle content="Michael Abrash's Graphics Programming Black Book, Special Edition">
|
|
<META name=vsauthor content="Michael Abrash">
|
|
<META name=vspublisher content="The Coriolis Group">
|
|
<META name=vspubdate content="07/01/97">
|
|
<META name=vscategory content="Web and Software Development: Game Development,Web and Software Development: Graphics and Multimedia Development">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<TITLE>Michael Abrash's Graphics Programming Black Book Special Edition: Assume Nothing</TITLE>
|
|
|
|
<!-- HEADER -->
|
|
<!-- Empty Reference Subhead -->
|
|
|
|
<!--ISBN=1576101746//-->
|
|
<!--TITLE=Michael Abrash's Graphics Programming Black Book Special Edition//-->
|
|
<!--AUTHOR=Michael Abrash//-->
|
|
<!--PUBLISHER=The Coriolis Group, Inc.//-->
|
|
<!--CHAPTER=03//-->
|
|
<!--PAGES=051-053//-->
|
|
<!--UNASSIGNED1//-->
|
|
<!--UNASSIGNED2//--></HEAD><BODY LINK=#0000FF ALINK=#000099 VLINK=#0000FF BGCOLOR=#FFFFFF>
|
|
|
|
<CENTER>
|
|
<TABLE BORDER>
|
|
<TR>
|
|
<TD><A HREF="03-05.html">Previous</A></TD>
|
|
<TD><A HREF="index.html">Table of Contents</A></TD>
|
|
<TD><A HREF="03-07.html">Next</A></TD>
|
|
</TR>
|
|
</TABLE>
|
|
</CENTER>
|
|
<P><BR></P>
|
|
<P>Listing 3.3 is used by naming it TESTCODE, assembling both Listing 3.2 (which includes TESTCODE) and Listing 3.1 with TASM or MASM, and linking the two resulting OBJ files together by way of the Borland orMicrosoft linker. Listing 3.4 shows a batch file, PZTIME.BAT, which does all that; when run, this batch file generates and runs the executable file PZTEST.EXE. PZTIME.BAT (Listing 3.4) assumes that the file PZTIMER.ASM contains Listing 3.1, and the file PZTEST.ASM contains Listing 3.2. The command-line parameter to PZTIME.BAT is the name of the file to be copied to TESTCODE and included into PZTEST.ASM. (Note that Turbo Assembler can be substituted for MASM by replacing “masm” with “tasm” and “link” with “tlink” in Listing 3.4. The same is true of Listing 3.7.)
|
|
</P>
|
|
<P><B>LISTING 3.4 PZTIME.BAT</B></P>
|
|
<!-- CODE //-->
|
|
<PRE>
|
|
echo off
|
|
rem
|
|
rem *** Listing 3.4 ***
|
|
rem
|
|
rem ***************************************************************
|
|
rem * Batch file PZTIME.BAT, which builds and runs the precision *
|
|
rem * Zen timer program PZTEST.EXE to time the code named as the *
|
|
rem * command-line parameter. Listing 3.1 must be named *
|
|
rem * PZTIMER.ASM, and Listing 3.2 must be named PZTEST.ASM. To *
|
|
rem * time the code in LST3-3, you’d type the DOS command: *
|
|
rem * *
|
|
rem * pztime lst3-3 *
|
|
rem * *
|
|
rem * Note that MASM and LINK must be in the current directory or *
|
|
rem * on the current path in order for this batch file to work. *
|
|
rem * *
|
|
rem * This batch file can be speeded up by assembling PZTIMER.ASM *
|
|
rem * once, then removing the lines: *
|
|
rem * *
|
|
rem * masm pztimer; *
|
|
rem * if errorlevel 1 goto errorend *
|
|
rem * *
|
|
rem * from this file. *
|
|
rem * *
|
|
rem * By Michael Abrash *
|
|
rem ***************************************************************
|
|
rem
|
|
rem Make sure a file to test was specified.
|
|
rem
|
|
if not x%1==x goto ckexist
|
|
echo ***************************************************************
|
|
echo * Please specify a file to test. *
|
|
echo ***************************************************************
|
|
goto end
|
|
rem
|
|
rem Make sure the file exists.
|
|
rem
|
|
:ckexist
|
|
if exist %1 goto docopy
|
|
echo ***************************************************************
|
|
echo * The specified file, “%1,” doesn’t exist. *
|
|
echo ***************************************************************
|
|
goto end
|
|
rem
|
|
rem copy the file to measure to TESTCODE.
|
|
rem
|
|
:docopy
|
|
copy %1 testcode
|
|
masm pztest;
|
|
if errorlevel 1 goto errorend
|
|
masm pztimer;
|
|
if errorlevel 1 goto errorend
|
|
link pztest+pztimer;
|
|
if errorlevel 1 goto errorend
|
|
pztest
|
|
goto end
|
|
:errorend
|
|
echo ***************************************************************
|
|
echo * An error occurred while building the precision Zen timer. *
|
|
echo ***************************************************************
|
|
:end
|
|
</PRE>
|
|
<!-- END CODE //-->
|
|
<P>Assuming that Listing 3.3 is named LST3-3.ASM and Listing 3.4 is named PZTIME.BAT, the code in Listing 3.3 would be timed with the command:
|
|
</P>
|
|
<!-- CODE SNIP //-->
|
|
<PRE>
|
|
pztime LST3-3.ASM
|
|
</PRE>
|
|
<!-- END CODE SNIP //-->
|
|
<P>which performs all assembly and linking, and reports the execution time of the code in Listing 3.3.
|
|
</P>
|
|
<P>When the above command is executed on an original 4.77 MHz IBM PC, the time reported by the Zen timer is 3619 µs, or about 3.62 µs per load of AL from memory. (While the exact number is 3.619 µs per load of AL, I’m going to round off that last digit from now on. No matter how many repetitions of a given instruction are timed, there’s just too much noise in the timing process—between dynamic RAM refresh, the prefetch queue, and the internal state of the processor at the start of timing—for that last digit to have any significance.) Given the test PC’s 4.77 MHz clock, this works out to about 17 cycles per <B>MOV</B>, which is actually a good bit longer than Intel’s specified 10-cycle execution time for this instruction. (See the MASM or TASM documentation, or Intel’s processor reference manuals, for official execution times.) Fear not, the Zen timer is right—<B>MOV AL,[MEMVAR]</B> really does take 17 cycles as used in Listing 3.3. Exactly why that is so is just what this book is all about.</P>
|
|
<P>In order to perform any of the timing tests in this book, enter Listing 3.1 and name it PZTIMER.ASM, enter Listing 3.2 and name it PZTEST.ASM, and enter Listing 3.4 and name it PZTIME.BAT. Then simply enter the listing you wish to run into the file <I>filename</I> and enter the command:</P>
|
|
<!-- CODE SNIP //-->
|
|
<PRE>
|
|
pztime <filename>
|
|
</PRE>
|
|
<!-- END CODE SNIP //-->
|
|
<P>In fact, that’s exactly how I timed each of the listings in this book. Code fragments you write yourself can be timed in just the same way. If you wish to time code directly in place in your programs, rather than in the test-bed program of Listing 3.2, simply insert calls to <B>ZTimerOn, ZTimerOff</B>, and <B>ZTimerReport</B> in the appropriate places and link PZTIMER to your program.</P>
|
|
<H3><A NAME="Heading12"></A><FONT COLOR="#000077">The Long-Period Zen Timer</FONT></H3>
|
|
<P>With a few exceptions, the Zen timer presented above will serve us well for the remainder of this book since we’ll be focusing on relatively short code sequences that generally take much less than 54 ms to execute. Occasionally, however, we will need to time longer intervals. What’s more, it is very likely that you will want to time code sequences longer than 54 ms at some point in your programming career. Accordingly, I’ve also developed a Zen timer for periods longer than 54 ms. The long-period Zen timer (so named by contrast with the precision Zen timer just presented) shown in Listing 3.5 can measure periods up to one hour in length.
|
|
</P>
|
|
<P>The key difference between the long-period Zen timer and the precision Zen timer is that the long-period timer leaves interrupts enabled during the timing period. As a result, timer interrupts are recognized by the PC, allowing the BIOS to maintain an accurate system clock time over the timing period. Theoretically, this enables measurement of arbitrarily long periods. Practically speaking, however, there is no need for a timer that can measure more than a few minutes, since the DOS time of day and date functions (or, indeed, the DATE and TIME commands in a batch file) serve perfectly well for longer intervals. Since very long timing intervals aren’t needed, the long-period Zen timer uses a simplified means of calculating elapsed time that is limited to measuring intervals of an hour or less. If a period longer than an hour is timed, the long-period Zen timer prints a message to the effect that it is unable to time an interval of that length.</P>
|
|
<P>For implementation reasons, the long-period Zen timer is also incapable of timing code that starts before midnight and ends after midnight; if that eventuality occurs, the long-period Zen timer reports that it was unable to time the code because midnight was crossed. If this happens to you, just time the code again, secure in the knowledge that at least you won’t run into the problem again for 23-odd hours.</P>
|
|
<P>You should not use the long-period Zen timer to time code that requires interrupts to be disabled for more than 54 ms at a stretch during the timing interval, since when interrupts are disabled the long-period Zen timer is subject to the same 54 ms maximum measurement time as the precision Zen timer.</P><P><BR></P>
|
|
<CENTER>
|
|
<TABLE BORDER>
|
|
<TR>
|
|
<TD><A HREF="03-05.html">Previous</A></TD>
|
|
<TD><A HREF="index.html">Table of Contents</A></TD>
|
|
<TD><A HREF="03-07.html">Next</A></TD>
|
|
</TR>
|
|
</TABLE>
|
|
</CENTER>
|
|
|
|
<hr width="90%" size="1" noshade>
|
|
<div align="center">
|
|
<font face="Verdana,sans-serif" size="1">Graphics Programming Black Book © 2001 Michael Abrash</font>
|
|
</div>
|
|
<!-- all of the reference materials (books) have the footer and subfoot reveresed -->
|
|
<!-- reference_subfoot = footer -->
|
|
<!-- reference_footer = subfoot -->
|
|
|
|
<!-- BEGIN SUB FOOTER -->
|
|
</BODY>
|
|
</HTML>
|
|
|
|
<!-- END FOOTER -->
|
|
|
|
|