/[dtapublic]/pubs/papers/20070526_cpu08_divu16_by_u16/cpu08div16by16a.tex
ViewVC logotype

Contents of /pubs/papers/20070526_cpu08_divu16_by_u16/cpu08div16by16a.tex

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10 - (show annotations) (download) (as text)
Fri Oct 7 03:23:35 2016 UTC (7 years, 8 months ago) by dashley
File MIME type: application/x-tex
File size: 22866 byte(s)
Commit of u16 = u16 / u16 analysis for the CPU08.
1 %$Header: /home/dashley/cvsrep/e3ft_gpl01/e3ft_gpl01/dtaipubs/cron/2007/cpu08div16by16a/cpu08div16by16a.tex,v 1.12 2007/05/26 18:25:46 dashley Exp $
2 %
3 \documentclass[letterpaper,10pt,titlepage]{article}
4 %
5 %\pagestyle{headings}
6 %
7 \usepackage{amsmath}
8 \usepackage{amsfonts}
9 \usepackage{amssymb}
10 \usepackage[ansinew]{inputenc}
11 \usepackage[OT1]{fontenc}
12 \usepackage{graphicx}
13 %\usepackage{makeidx}
14 %
15 %Contributed by Robin Fairbairns of the comp.text.tex newsgroup. I have no
16 %idea how it works ... but it gives a working \bdiv.
17 %
18 \makeatletter
19 \def\bdiv{%
20 \nonscript\mskip-\medmuskip\mkern5mu%
21 \mathbin{\operator@font div}\penalty900\mkern5mu%
22 \nonscript\mskip-\medmuskip}
23 \makeatother
24 %
25 %
26 \begin{document}
27 \title{Notes on Economical 16/16 = 16 Unsigned Integer Division on the Freescale CPU08}
28 \author{\vspace{1cm}\\David T. Ashley\\\texttt{dta@e3ft.com}\\\vspace{1cm}}
29 \date{\vspace*{8mm}\small{Version Control $ $Revision: 1.12 $ $ \\
30 Version Control $ $Date: 2007/05/26 18:25:46 $ $ (UTC) \\
31 $ $RCSfile: cpu08div16by16a.tex,v $ $ \\
32 \LaTeX{} Compilation Date: \today{}}}
33 \maketitle
34
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 %
37 \begin{abstract}
38 This document contains my notes on attempting to optimize
39 the 16 = 16/16 unsigned integer division subroutine distributed with
40 a Freescale CPU08 compiler. I attempted to replace the standard
41 shift-compare-subtract algorithm with Knuth's algorithm.
42
43 In the end, the attempt was mostly a failure. There seemed to be no way
44 to gain the execution time advantages of Knuth's algorithm without increasing
45 FLASH size. (The goal would have been to obtain more favorable
46 execution time \emph{and} FLASH size, rather than a tradeoff.)
47 \end{abstract}
48
49 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
50
51 \section{Introduction and Overview}
52 \label{siov0}
53
54 The fundamental goal of practical computer integer arithmetic is to obtain
55 an exact result using machine instructions that are as fast and compact as
56 possible.
57
58 For three of the four fundamental operations (addition, subtraction, and
59 multiplication), it is intuitively obvious to most programmers how to
60 use existing machine instructions to operate on operands that are larger
61 than the machine instructions can accommodate.
62
63 The fourth fundamental operation (division), however, is less well understood
64 by a typical programmer than the other three. It is not obvious to most
65 programmers how to use machine division instructions to divide integers larger
66 than the native machine division instructions will accommodate.
67
68 In 2007, I noticed that the integer division library functions associated with
69 a particular \emph{C} compiler were of the shift-compare-subtract variety.
70 As the CPU08 has a 16/16=8 native division instruction, I suspected but was not
71 sure that the 16/16=16 division function could be improved.
72
73 Note that for a library function used by a \emph{C} compiler, it may not
74 be necessary (although it may be desirable) to calculate the quotient and the
75 remainder at the same time. An algorithm that calculates the quotient but
76 does not calculate the remainder, or vice-versa, may be acceptable for
77 use by compiled code.
78
79 Although I haven't examined the \emph{C} standards, I doubt that there is
80 any special requirement for the quotient or remainder calculated when
81 the denominator is zero. The only requirement is probably that the calculation
82 not continue indefinitely (i.e. not an infinite loop).
83
84 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
85
86 \section{Nomenclature and Notation}
87 \label{snom0}
88
89 I use the nomenclature ``16/16=16 division'' to denote a division function that
90 accepts a 16-bit unsigned numerator and a 16-bit unsigned denominator; and
91 produces either/both a 16-bit quotient and a 16-bit remainder.
92
93 I use $n$ to denote the numerator, $d$ to denote the denominator, $q$ to denote
94 the integer quotient, and $r$ to denote the remainder.
95
96 Any of the 16-bit quantities can be subscripted with ``H'' or ``L'' to denote
97 the most-significant or least-significant byte. For example,
98
99 \begin{equation}
100 \label{eq:snom0:01}
101 n = 2^8 n_H + n_L .
102 \end{equation}
103
104 Within any of the 16-bit quantities, bits are subscripted in the traditional fashion.
105 For example,
106
107 \begin{equation}
108 \label{eq:snom0:02}
109 n = \sum_{i=0}^{15} 2^i n_i .
110 \end{equation}
111
112 Within any of the 8-bit quantities, bits are also subscripted in the traditional fashion.
113 For example,
114
115 \begin{equation}
116 \label{eq:snom0:03}
117 n = 2^8 \sum_{i=0}^{7} 2^i n_{H_i} + \sum_{i=0}^{7} 2^i n_{L_i}
118 = \sum_{i=0}^{7} 2^{i+8} n_{H_i} + \sum_{i=0}^{7} 2^i n_{L_i} .
119 \end{equation}
120
121 Because only non-negative integers are involved, \emph{floor()} and
122 \emph{div} are used interchangeably, i.e.
123
124 \begin{equation}
125 \label{eq:snom0:04}
126 \left\lfloor \frac{a}{b} \right\rfloor = a \bdiv b, \;\; a,b \geq 0 .
127 \end{equation}
128
129 An identity that is frequently used in this document is
130
131 \begin{eqnarray}
132 \label{eq:snom0:05}
133 \frac{a}{b} & = & a \bdiv b + \frac{a \bmod b}{b} \\
134 \label{eq:snom0:06}
135 & = & \left\lfloor \frac{a}{b} \right\rfloor + \frac{a \bmod b}{b} .
136 \end{eqnarray}
137
138
139 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
140
141 \section{Analysis of Existing Code}
142 \label{saec0}
143
144 This section presents an analysis of the behavior and characteristics of
145 the existing code.
146
147
148 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
149
150 \subsection{Listing}
151 \label{saec0:slec0}
152
153 The existing code is reproduced below, with line numbers.
154
155 \begin{verbatim}
156 001: c_umod:
157 002: bsr c_udiv ; divide
158 003: pshh ; transfer MSB
159 004: pula ; in place
160 005: sta c_reg
161 006: txa ; LSB in place
162 007: rts ; and return
163 008: ;
164 009: c_udiv:
165 010: psha ; save NL
166 011: pshh ; DH on the stack
167 012: tst 1,sp ; test zero
168 013: bne full ; full division
169 014: pulh ; clean stack
170 015: cpx c_reg ; compare DL with NH
171 016: bls half ; half division
172 017: lda c_reg ; NH
173 018: psha ; in
174 019: pulh ; H
175 020: pula ; NL in A
176 021: div ; DL in X, divide
177 022: clr c_reg ; QH is zero
178 023: fini:
179 024: pshh ; move RL
180 025: pulx ; in X
181 026: clrh ; RH is zero
182 027: rts ; and return
183 028: half:
184 029: lda c_reg ; NH in A
185 030: clrh ; 1st divide 8 X 8
186 031: div ; divide
187 032: sta c_reg ; QH in place
188 033: pula ; complete dividend with NL
189 034: div ; divide
190 035: bra fini ; complete remainder
191 036: full:
192 037: pshx ; save DL
193 038: ldx #8 ; counter
194 039: clra ; Extention
195 040: pshx ; save on
196 041: psha ; the stack
197 042: tsx ; stack addressed by H:X
198 043: bcl:
199 044: lsl 4,x ; shift E:NH:NL
200 045: rol c_reg ; left
201 046: rola
202 047: sta 0,x ; store E
203 048: cmp 3,x ; compare DH
204 049: blo next ; too low, continue
205 050: bne ok ; ok to subtract
206 051: lda c_reg ; compare NH
207 052: sub 2,x ; with DL
208 053: bhs ok2 ; ok, complete result
209 054: lda 0,x ; restore value
210 055: bra next ; and continue
211 056: ok:
212 057: lda c_reg ; substract D
213 058: sub 2,x ; from E:NH
214 059: ok2:
215 060: sta c_reg ; in place
216 061: lda 0,x
217 062: sbc 3,x
218 063: inc 4,x ; set result bit
219 064: next:
220 065: dbnz 1,x,bcl ; count down and loop
221 066: sta 0,x ; store E
222 067: pulh ; RH in place
223 068: ais #3 ; clean up stack
224 069: ldx c_reg ; RL in place
225 070: pula ; QL in place
226 071: clr c_reg ; QH is zero
227 072: rts ; and return
228 \end{verbatim}
229
230
231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
232
233 \subsection{Algorithmic Analysis}
234 \label{saec0:saan0}
235
236 The algorithm is divided into two cases:
237
238 \begin{itemize}
239 \item Case I: $d_H = 0$ (lines 14-35).
240 \item Case II: $d_H > 0$ (lines 36-72).
241 \end{itemize}
242
243
244 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
245
246 \subsubsection{Case I}
247 \label{saec0:saan0:scas0}
248
249 In the case of $d_H = 0$, the division is 16/8:
250
251 \begin{eqnarray}
252 \label{eq:saec0:saan0:scas0:01}
253 \frac{2^8 n_H + n_L}{d_L} & = & \frac{2^8 n_H}{d_L} + \frac{n_L}{d_L} \\
254 \label{eq:saec0:saan0:scas0:02}
255 & = & 2^8 \left( n_H \bdiv d_L + \frac{n_H \bmod d_L}{d_L} \right) + \frac{n_L}{d_L} \\
256 \label{eq:saec0:saan0:scas0:03}
257 & = & 2^8 (n_H \bdiv d_L) + \frac{2^8 (n_H \bmod d_L) + n_L}{d_L}
258 \end{eqnarray}
259
260 (\ref{eq:saec0:saan0:scas0:03}) is an exact expression involving rational numbers.
261 However, we don't want to calculate the left side of (\ref{eq:saec0:saan0:scas0:03});
262 rather, we wish to calculate its \emph{floor()}\@. Applying the
263 \emph{floor()} function to both sides of (\ref{eq:saec0:saan0:scas0:03}) yields:
264
265 \begin{equation}
266 \label{eq:saec0:saan0:scas0:04}
267 \left\lfloor \frac{2^8 n_H + n_L}{d_L} \right\rfloor
268 =
269 2^8 (n_H \bdiv d_L) + \left\lfloor \frac{2^8 (n_H \bmod d_L) + n_L}{d_L} \right\rfloor .
270 \end{equation}
271
272 Note that (\ref{eq:saec0:saan0:scas0:04}) is in a form
273 that can be readily evaluated using a processor with 16/8 division
274 capability; so long as
275
276 \begin{equation}
277 \label{eq:saec0:saan0:scas0:05}
278 \frac{2^8 (n_H \bmod d_L) + n_L}{d_L} < 2^8 ,
279 \end{equation}
280
281 \noindent{}a fact that can be easily verified by the reader.
282
283 (\ref{eq:saec0:saan0:scas0:04}) can be readily evaluated by a processor with
284 16/8 division capability because such a division instruction always provides
285 both quotient and remainder. It is easy to see that (\ref{eq:saec0:saan0:scas0:04})
286 can be evaluated with a division, a re-staging of bytes, and a second division.
287
288 If (\ref{eq:saec0:saan0:scas0:04}) is evaluated as suggested, it needs to be verified
289 whether the remainder of the second division is the same as the remainder
290 of the larger division, i.e.
291
292 \begin{equation}
293 \label{eq:saec0:saan0:scas0:06}
294 (2^8 n_H + n_L) \bmod d_L =? ((2^8 \bmod d_L) + n_L) \bmod d_L.
295 \end{equation}
296
297 The question of whether (\ref{eq:saec0:saan0:scas0:06}) is an
298 equality is the question of whether
299
300 \begin{equation}
301 \label{eq:saec0:saan0:scas0:07}
302 ka \bmod b = (k (a \bmod b)) \bmod b .
303 \end{equation}
304
305 In order to prove or disprove (\ref{eq:saec0:saan0:scas0:07}),
306 decompose $a$ into $ib + j$. Then, since $kib \bmod b = 0$,
307
308 \begin{eqnarray}
309 \label{eq:saec0:saan0:scas0:08}
310 k (ib + j) \bmod b & = & k j \bmod b \\
311 \label{eq:saec0:saan0:scas0:09}
312 k j \bmod b & = & k j \bmod b .
313 \end{eqnarray}
314
315 Thus, if (\ref{eq:saec0:saan0:scas0:04}) is evaluated as suggested (with
316 two divisions), the final remainder will be the same as the remainder for the
317 original division. (\ref{eq:saec0:saan0:scas0:04}) will, in fact, deliver both
318 the quotient and remainder economically.
319
320 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
321
322 \subsubsection{Case II}
323 \label{saec0:saan0:scas1}
324
325 The case of $d_H > 0$ (\S{}\ref{saec0:slec0}, lines 36-72) is conventional
326 shift-compare-subtract division. Only eight iterations of the loop are required
327 because with $d_H > 0$, $d \geq 2^8$, and $n/d < 2^8$.
328
329
330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
331
332 \subsection{Timing Analysis}
333 \label{saec0:stan0}
334
335 The code of \S{}\ref{saec0:slec0} is reproduced below, with instruction
336 timing (number of clocks) and FLASH requirements (number of bytes) added
337 as (clocks/bytes). It was determined that \emph{c\_reg} resides
338 in zero-page (i.e. \emph{direct}) memory.
339
340 \begin{verbatim}
341 001: c_umod:
342 002: bsr c_udiv 4/2 ; divide
343 003: pshh ; transfer MSB
344 004: pula 2/1 ; in place
345 005: sta c_reg 3/2
346 006: txa 1/1 ; LSB in place
347 007: rts 4/1 ; and return
348 008: ;
349 009: c_udiv:
350 010: psha 2/1 ; save NL
351 011: pshh 2/1 ; DH on the stack
352 012: tst 1,sp 4/3 ; test zero
353 013: bne full 3/2 ; full division
354 014: pulh 2/1 ; clean stack
355 015: cpx c_reg 3/2 ; compare DL with NH
356 016: bls half 3/2 ; half division
357 017: lda c_reg 3/2 ; NH
358 018: psha 2/1 ; in
359 019: pulh 2/1 ; H
360 020: pula 2/1 ; NL in A
361 021: div 7/1 ; DL in X, divide
362 022: clr c_reg 3/2 ; QH is zero
363 023: fini:
364 024: pshh 2/1 ; move RL
365 025: pulx 2/1 ; in X
366 026: clrh 1/1 ; RH is zero
367 027: rts 4/1 ; and return
368 028: half:
369 029: lda c_reg 3/2 ; NH in A
370 030: clrh 1/1 ; 1st divide 8 X 8
371 031: div 7/1 ; divide
372 032: sta c_reg 3/2 ; QH in place
373 033: pula 2/1 ; complete dividend with NL
374 034: div 7/1 ; divide
375 035: bra fini 3/2 ; complete remainder
376 036: full:
377 037: pshx 2/1 ; save DL
378 038: ldx #8 2/2 ; counter
379 039: clra 1/1 ; Extention
380 040: pshx 2/1 ; save on
381 041: psha 2/1 ; the stack
382 042: tsx 2/1 ; stack addressed by H:X
383 043: bcl:
384 044: lsl 4,x 4/2 ; shift E:NH:NL
385 045: rol c_reg 4/2 ; left
386 046: rola 1/1
387 047: sta 0,x 2/1 ; store E
388 048: cmp 3,x 3/2 ; compare DH
389 049: blo next 3/2 ; too low, continue
390 050: bne ok 3/2 ; ok to subtract
391 051: lda c_reg 3/2 ; compare NH
392 052: sub 2,x 3/2 ; with DL
393 053: bhs ok2 3/2 ; ok, complete result
394 054: lda 0,x 2/1 ; restore value
395 055: bra next 3/2 ; and continue
396 056: ok:
397 057: lda c_reg 3/2 ; substract D
398 058: sub 2,x 3/2 ; from E:NH
399 059: ok2:
400 060: sta c_reg 3/2 ; in place
401 061: lda 0,x 2/1
402 062: sbc 3,x 3/2
403 063: inc 4,x 3/2 ; set result bit
404 064: next:
405 065: dbnz 1,x,bcl 5/3 ; count down and loop
406 066: sta 0,x 2/1 ; store E
407 067: pulh 2/1 ; RH in place
408 068: ais #3 2/2 ; clean up stack
409 069: ldx c_reg 3/2 ; RL in place
410 070: pula 2/1 ; QL in place
411 071: clr c_reg 3/2 ; QH is zero
412 072: rts 4/1 ; and return
413 \end{verbatim}
414
415 There are three distinct timing cases for the \emph{c\_udiv} function:
416
417 \begin{enumerate}
418 \item $d_H = 0$ and $n_H < d_L$:
419 47 clocks are required, representing straight flow of the
420 instructions from line 10 through line 27.
421 \item $d_H = 0$ and $n_H \geq d_L$: 54 clocks are required.
422 \item $d_H > 0$ and every bit of the quotient is 1, in which case
423 400 clocks are required. This represents 22 clocks up through
424 line 42, 45 clocks $\times$ 8 in the lines from 43 through 65, and
425 18 clocks in the lines from 66 through 72.
426 \end{enumerate}
427
428
429 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
430
431 \subsection{FLASH/RAM Consumption Analysis}
432 \label{saec0:sfra0}
433
434 From \S{}\ref{saec0:stan0}, 93 bytes of FLASH are used. Only one byte
435 of RAM is used (\emph{c\_reg}, probably shared with other functions
436 as well).
437
438
439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
440
441 \section{Potential Optimizations}
442 \label{spop0}
443
444
445 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
446
447 \subsection{Potential Case I Optimizations}
448 \label{spop0:scas0}
449
450 This section corresponds to \emph{Case I} of \S{}\ref{saec0:saan0:scas0}.
451
452 The most obvious observation about the code (\S{}\ref{saec0:slec0}) is that
453 division instructions are very inexpensive on the CPU08---7 clock cycles,
454 or about 2 typical instructions. Branching based on
455 $n_H \geq d_L$
456 (\S{}\ref{saec0:slec0}, lines 15-16)
457 may cost more in the test, the branch, and in other
458 data transfer overhead than is saved. It may make sense to apply the
459 full formula in (\ref{eq:saec0:saan0:scas0:04}) in all cases where
460 $d_H = 0$.
461
462 When $d_H = 0$, and if one assumes normal distribution of data, the expected
463 value of execution time is about $(47+54)/2 = 50.5$ clocks.\footnote{If the
464 data is assumed normally distributed, $n_H$ has about a 0.5 probability of being at least as large
465 as $d_L$.}
466
467 The code below combines two of the three timing cases into one by ignoring the
468 relationship between $n_H$ and $d_L$.
469
470 \begin{verbatim}
471 ;Condition at function entry:
472 ;N_H in 1,SP
473 ;N_L in A
474 ;D_H in H
475 ;D_L in X
476 ;
477 ;Condition at function exit:
478 ;Q_H in c_reg
479 ;Q_L in A
480 ;R_H in H
481 ;R_L in X
482 ;
483 c_udiv:
484 psha 2/1 ; save NL
485 pshh 2/1 ; DH on the stack
486 tst 1,sp 4/3 ; test zero
487 bne full 3/2 ; full division
488 ;
489 ;From here on we're committed to the division with
490 ;arbitary numerator, and denominator <= 255.
491 ; N_H at 3,sp
492 ; N_L at 2,sp
493 ; D_H at 1,sp
494 ;
495 clrh 1/1
496 lda 3,sp 4/3 ; H:A now contains N_H
497 div 7/1 ; divide
498 sta c_reg 3/2 ; QH in place
499 lda 2,sp 4/3 ; complete dividend with NL
500 div 7/1 ; divide. Q_L in A, R_L in H
501 pshh 2/1 ; move RL
502 pulx 2/1 ; in X
503 clrh 1/1 ; RH is zero
504 ais #3 2/2 ; clean stack
505 rts 4/1 ; and return
506 \end{verbatim}
507
508 Although the code does raise the minimum execution time from 47 to
509 48 clocks:
510
511 \begin{itemize}
512 \item It lowers the expected value of the $d_H=0$ execution time from
513 50.5 to 48 clocks.
514 \item It saves approximately 15 bytes of FLASH.
515 \end{itemize}
516
517 This optimization is recommended.
518
519
520 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
521
522 \subsection{Potential Case II Optimizations}
523 \label{spop0:scas1}
524
525 This section corresponds to \emph{Case II} of \S{}\ref{saec0:saan0:scas1}.
526
527 I sent an e-mail to an engineer at the compiler manufacturer indicating
528 that:
529
530 \begin{itemize}
531 \item I believed \emph{Case I} could be optimized as indicated earlier
532 in the document.
533 \item I believed \emph{Case II} could be optimized by applying Knuth's
534 algorithm.
535 \end{itemize}
536
537 The reply I received from the compiler manufacturer was that:
538
539 \begin{itemize}
540 \item There was agreeement about \emph{Case I}.
541 \item \emph{Case II} may be a little faster using Knuth's algorithm, but would
542 definitely be larger (code used to evaluate the application of Knuth's
543 algorithm was also provided).
544 \end{itemize}
545
546 In the test code provided by the compiler manufacturer, the approach used was
547 to obtain a trial quotient and then to subtract the divisor from the remainder
548 up to twice to adjust the quotient up to 2 counts downward (Knuth's algorithm).
549
550 I did try a different approach (to iterate on the quotient and to reconstruct
551 $q \times d$ with decreasing $q$). This approach promised to be slightly more
552 compact because $q \times d$ reconstruction was reutilized. However, it worked out
553 to occupy about 153 bytes rather than 103 for the shift-compare-subtract
554 algorithm (timing was not examined). (This test code is version-controlled
555 in the same directory as this \LaTeX{} document.)
556
557 At this point I agree with the
558 compiler manufacturer
559 that there is a tradeoff between size and speed (it seems
560 nearly impossible to get both).
561
562 In any reimplementation of this algorithm, will probably need to choose between
563 size and speed. I believe there is some possibility to reduce the reimplementation
564 from 153 bytes, but not down to 103 bytes.
565
566 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
567 \end{document}
568 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
569 % $Log: cpu08div16by16a.tex,v $
570 % Revision 1.12 2007/05/26 18:25:46 dashley
571 % Edits to incorporate final thoughts (for now) and test code results.
572 %
573 % Revision 1.11 2007/05/21 16:49:40 dashley
574 % \bdiv functionality as suggested by Robin Fairbairns added.
575 %
576 % Revision 1.10 2007/05/18 15:53:59 dashley
577 % Edits.
578 %
579 % Revision 1.9 2007/05/18 02:02:56 dashley
580 % Edits.
581 %
582 % Revision 1.8 2007/05/18 02:02:10 dashley
583 % Edits.
584 %
585 % Revision 1.7 2007/05/18 01:40:20 dashley
586 % Edits.
587 %
588 % Revision 1.6 2007/05/18 00:15:56 dashley
589 % Edits.
590 %
591 % Revision 1.5 2007/05/17 15:53:57 dashley
592 % Edits.
593 %
594 % Revision 1.4 2007/05/17 14:46:34 dashley
595 % Edits.
596 %
597 % Revision 1.3 2007/05/17 04:15:22 dashley
598 % Edits.
599 %
600 % Revision 1.2 2007/05/17 03:50:48 dashley
601 % Edits.
602 %
603 % Revision 1.1 2007/05/17 03:09:06 dashley
604 % Initial checkin.
605 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25