193 lines
9.6 KiB
HTML
193 lines
9.6 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: Floating-Point for Real-Time 3-D</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=63//-->
|
|
<!--PAGES=1170-1173//-->
|
|
<!--UNASSIGNED1//-->
|
|
<!--UNASSIGNED2//--></HEAD><BODY LINK=#0000FF ALINK=#000099 VLINK=#0000FF BGCOLOR=#FFFFFF>
|
|
|
|
<CENTER>
|
|
<TABLE BORDER>
|
|
<TR>
|
|
<TD><A HREF="63-02.html">Previous</A></TD>
|
|
<TD><A HREF="index.html">Table of Contents</A></TD>
|
|
<TD><A HREF="63-04.html">Next</A></TD>
|
|
</TR>
|
|
</TABLE>
|
|
</CENTER>
|
|
<P><BR></P>
|
|
<P><B>Listing 63.2 1 L63-2.ASM</B></P>
|
|
<!-- CODE //-->
|
|
<PRE>
|
|
; unoptimized dot product; 17 cycles
|
|
fld [vec0+0] ;starts & ends on cycle 0
|
|
fmul [vec1+0] ;starts on cycle 1
|
|
fld [vec0+4] ;starts & ends on cycle 2
|
|
fmul [vec1+4] ;starts on cycle 3
|
|
fld [vec0+8] ;starts & ends on cycle 4
|
|
fmul [vec1+8] ;starts on cycle 5
|
|
;stalls for cycles 6-7
|
|
faddp st(1),st(0) ;starts on cycle 8
|
|
;stalls for cycles 9-10
|
|
faddp st(1),st(0) ;starts on cycle 11
|
|
;stalls for cycles 12-14
|
|
fstp [dot] ;starts on cycle 15,
|
|
; ends on cycle 16
|
|
</PRE>
|
|
<!-- END CODE //-->
|
|
<P><B>Listing 63.3 L63-3.ASM</B></P>
|
|
<!-- CODE //-->
|
|
<PRE>
|
|
;optimized dot product; 15 cycles
|
|
fld [vec0+0] ;starts & ends on cycle 0
|
|
fmul [vec1+0] ;starts on cycle 1
|
|
fld [vec0+4] ;starts & ends on cycle 2
|
|
fmul [vec1+4] ;starts on cycle 3
|
|
fld [vec0+8] ;starts & ends on cycle 4
|
|
fmul [vec1+8] ;starts on cycle 5
|
|
fxch st(1) ;no cost
|
|
faddp st(2),st(0) ;starts on cycle 6
|
|
;stalls for cycles 7-8
|
|
faddp st(1),st(0) ;starts on cycle 9
|
|
;stalls for cycles 10-12
|
|
fstp [dot] ;starts on cycle 13,
|
|
; ends on cycle 14
|
|
</PRE>
|
|
<!-- END CODE //-->
|
|
<H3><A NAME="Heading8"></A><FONT COLOR="#000077">The Cross Product</FONT></H3>
|
|
<P>When last we looked at the cross product, we found that it’s handy for generating a vector that’s normal to two other vectors. The cross product is calculated as [u<SUB>2</SUB>v<SUB>3</SUB>-u<SUB>3</SUB>v<SUB>2</SUB> u<SUB>3</SUB>v<SUB>1</SUB>-u<SUB>1</SUB>v<SUB>3</SUB> u<SUB>1</SUB>v<SUB>2</SUB>-u<SUB>2</SUB>v<SUB>1</SUB>]. The theoretical minimum cycle count for the cross product is 21 cycles. Listing 63.4 shows a straightforward implementation that calculates each component of the result separately, losing 15 cycles to stalls.</P>
|
|
<P><B>Listing 63.4 L63-4.ASM</B></P>
|
|
<!-- CODE //-->
|
|
<PRE>
|
|
;unoptimized cross product; 36 cycles
|
|
fld [vec0+4] ;starts & ends on cycle 0
|
|
fmul [vec1+8] ;starts on cycle 1
|
|
fld [vec0+8] ;starts & ends on cycle 2
|
|
fmul [vec1+4] ;starts on cycle 3
|
|
;stalls for cycles 4-5
|
|
fsubrp st(1),st(0) ;starts on cycle 6
|
|
;stalls for cycles 7-9
|
|
fstp [vec2+0] ;starts on cycle 10,
|
|
; ends on cycle 11
|
|
fld [vec0+8] ;starts & ends on cycle 12
|
|
fmul [vec1+0] ;starts on cycle 13
|
|
fld [vec0+0] ;starts & ends on cycle 14
|
|
fmul [vec1+8] ;starts on cycle 15
|
|
;stalls for cycles 16-17
|
|
fsubrp st(1),st(0) ;starts on cycle 18
|
|
;stalls for cycles 19-21
|
|
fstp [vec2+4] ;starts on cycle 22,
|
|
; ends on cycle 23
|
|
|
|
fld [vec0+0] ;starts & ends on cycle 24
|
|
fmul [vec1+4] ;starts on cycle 25
|
|
fld [vec0+4] ;starts & ends on cycle 26
|
|
fmul [vec1+0] ;starts on cycle 27
|
|
;stalls for cycles 28-29
|
|
fsubrp st(1),st(0) ;starts on cycle 30
|
|
;stalls for cycles 31-33
|
|
fstp [vec2+8] ;starts on cycle 34,
|
|
; ends on cycle 35
|
|
</PRE>
|
|
<!-- END CODE //-->
|
|
<P>We couldn’t get rid of many of the stalls in the dot product code because with six inputs and one output, it was impossible to interleave all the operations. However, the cross product, with three outputs, is much more amenable to optimization. In fact, three is the magic number; because we have three calculation streams and the latency of FADD, FSUB, and FMUL is 3 cycles, we can eliminate almost every single stall in the cross-product calculation, as shown in Listing 63.5. Listing 63.5 loses only one cycle to a stall, the cycle before the first FST; the relevant FSUB has just finished on the preceding cycle, so we run into the extra cycle of latency associated with FST. Listing 63.5 is more than 60 percent faster than Listing 63.4, a striking illustration of the power of properly managing the Pentium’s FP pipeline.
|
|
</P>
|
|
<P><B>Listing 63.5 L63-5.ASM</B></P>
|
|
<!-- CODE //-->
|
|
<PRE>
|
|
;optimized cross product; 22 cycles
|
|
fld [vec0+4] ;starts & ends on cycle 0
|
|
fmul [vec1+8] ;starts on cycle 1
|
|
fld [vec0+8] ;starts & ends on cycle 2
|
|
fmul [vec1+0] ;starts on cycle 3
|
|
fld [vec0+0] ;starts & ends on cycle 4
|
|
fmul [vec1+4] ;starts on cycle 5
|
|
fld [vec0+8] ;starts & ends on cycle 6
|
|
fmul [vec1+4] ;starts on cycle 7
|
|
fld [vec0+0] ;starts & ends on cycle 8
|
|
fmul [vec1+8] ;starts on cycle 9
|
|
fld [vec0+4] ;starts & ends on cycle 10
|
|
fmul [vec1+0] ;starts on cycle 11
|
|
fxch st(2) ;no cost
|
|
fsubrp st(5),st(0) ;starts on cycle 12
|
|
fsubrp st(3),st(0) ;starts on cycle 13
|
|
fsubrp st(1),st(0) ;starts on cycle 14
|
|
fxch st(2) ;no cost
|
|
;stalls for cycle 15
|
|
fstp [vec2+0] ;starts on cycle 16,
|
|
; ends on cycle 17
|
|
fstp [vec2+4] ;starts on cycle 18,
|
|
; ends on cycle 19
|
|
fstp [vec2+8] ;starts on cycle 20,
|
|
; ends on cycle 21
|
|
</PRE>
|
|
<!-- END CODE //-->
|
|
<H3><A NAME="Heading9"></A><FONT COLOR="#000077">Transformation</FONT></H3>
|
|
<P>Transforming a point, for example from worldspace to viewspace, is one of the most heavily used FP operations in realtime 3-D. Conceptually, transformation is nothing more than three dot products and three additions, as I will discuss in Chapter 61. (Note that I’m talking about a subset of a general 4×4 transformation matrix, where the fourth row is always implicitly [0 0 0 1]. This limited form suffices for common transformations, and does 25 percent less work than a full 4×4 transformation.)
|
|
</P>
|
|
<P>Transformation is calculated as:</P>
|
|
<!-- CODE SNIP //-->
|
|
<PRE>
|
|
- - - - - -
|
|
v<SUB>1</SUB> m<SUB>11</SUB> m<SUB>12</SUB> m<SUB>13</SUB> m<SUB>14</SUB> u<SUB>1</SUB>
|
|
v<SUB>2</SUB> = m<SUB>21</SUB> m<SUB>22</SUB> m<SUB>23</SUB> m<SUB>24</SUB> u<SUB>2</SUB>
|
|
v<SUB>3</SUB> m<SUB>31</SUB> m<SUB>32</SUB> m<SUB>33</SUB> m<SUB>34</SUB> u<SUB>3</SUB>
|
|
1 0 0 0 1 1
|
|
- - - - - -
|
|
</PRE>
|
|
<!-- END CODE SNIP //-->
|
|
<P>or
|
|
</P>
|
|
<!-- CODE SNIP //-->
|
|
<PRE>
|
|
v<SUB>1</SUB> = m<SUB>11</SUB>u<SUB>1</SUB> + m<SUB>12</SUB>u<SUB>2</SUB> + m<SUB>13</SUB>u<SUB>3</SUB> + m<SUB>14</SUB>
|
|
v<SUB>2</SUB> = m<SUB>21</SUB>u<SUB>1</SUB> + m<SUB>22</SUB>u<SUB>2</SUB> + m<SUB>23</SUB>u<SUB>3</SUB> + m<SUB>24</SUB>
|
|
v<SUB>3</SUB> = m<SUB>31</SUB>u<SUB>1</SUB> + m<SUB>32</SUB>u<SUB>2</SUB> + m<SUB>33</SUB>u<SUB>3</SUB> + m<SUB>34.</SUB>
|
|
</PRE>
|
|
<!-- END CODE SNIP //-->
|
|
<P><BR></P>
|
|
<CENTER>
|
|
<TABLE BORDER>
|
|
<TR>
|
|
<TD><A HREF="63-02.html">Previous</A></TD>
|
|
<TD><A HREF="index.html">Table of Contents</A></TD>
|
|
<TD><A HREF="63-04.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 -->
|
|
|
|
|