home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / arch / 10915 < prev    next >
Encoding:
Internet Message Format  |  1992-11-19  |  7.3 KB

  1. Xref: sparky comp.arch:10915 comp.lang.misc:3788
  2. Newsgroups: comp.arch,comp.lang.misc
  3. Path: sparky!uunet!haven.umd.edu!darwin.sura.net!Sirius.dfn.de!Urmel.Informatik.RWTH-Aachen.DE!martin
  4. From: martin@math.rwth-aachen.de (  Martin Schoenert)
  5. Subject: Re: how to advocate new software/hardware features (Re: Hardware Support for Numeric Algorithms)
  6. Message-ID: <martin.722176263@bert>
  7. Sender: news@Urmel.Informatik.RWTH-Aachen.DE (Newsfiles Owner)
  8. Nntp-Posting-Host: bert.math.rwth-aachen.de
  9. Organization: Rechnerbetrieb Informatik  /  RWTH Aachen
  10. References: <TMB.92Nov14145619@pollux.idiap.ch> <Bxq7y0.IJ@mentor.cc.purdue.edu> <mwm.2n6z@contessa.palo-alto.ca.us> <Bxr8vG.IpI@mentor.cc.purdue.edu> <martin.721995695@bert>
  11. Date: 19 Nov 92 12:31:03 GMT
  12. Lines: 141
  13.  
  14. I have had two replies to my original post, and from them it appears that
  15. I didn't get my point across.  So let me try again.
  16.  
  17. 1)  I want to write a *large integer arithmetic package in C*  that  lets
  18.     me work with integers of several  hundred  or  thousands  of  digits.
  19.     For the  sake of  discussion  let  us assume that  I  am  really only
  20.     interested in addition and multiplication of such integers (I include
  21.     addition only to avoid  that people tell me that I should use modular
  22.     techniques).
  23.  
  24. 2)  I want to write a portable package that can be used with  every  ANSI
  25.     conforming compiler.  That means that I  cannot  use  extension  such
  26.     as GNU C 'asm' statements, I cannot  use  nonstandard  integer  types
  27.     such as 'long long'.
  28.  
  29. 3)  I want to make the functions in this  package  as  fast  as possible,
  30.     since I am going to use them a lot.
  31.  
  32. The datastructure for such a  large  integer is  simple enough.  A  large
  33. integer  is  represented  by  an   array  of  *digits*.   Each  digit  is
  34. represented  by an unsigned integer type  provided by the compiler (maybe
  35. 16 bit, 32 bit, or something else).  Let B be the smallest positive value
  36. that cannot  be represented as a digit (e.g. 2^16, or 2^32, or whatever).
  37. For example, suppose  a digit  is an  unsigned short and this  is 16  bit
  38. wide.  Then B = 2^16, and the integer represented by the array  'unsigned
  39. short v[] = {58368,21515,2}' is 58368 + 21515*2^16 + 2*2^32 = 10^10.
  40.  
  41. Now the  algorithm used to  multiply such large  integers  is  the one we
  42. learned in school (with B=10).  I know that there are algorithms that are
  43. asymptotically faster  than  this  (e.g. Karatsuba  or even FFT), but for
  44. integers  less than a  certain  size (about 100 decimal digits)  they are
  45. usually slower.
  46.  
  47. This algorithm requires that we can multiply digits.   Indeed in practice
  48. it spends most of its time multiplying digits.
  49.  
  50. Now this means that the type  used for digits  is small  enough such that
  51. there is an unsigned integer type  that is at least twice as wide.   More
  52. often than not this means that a digit is 'unsigned short' and the result
  53. of a  multiplication is 'unsigned long' (and  on most  modern  processors
  54. this will  mean  that  digits  are  16  bit wide  and  the  result  of  a
  55. multiplication is 32 bit wide).
  56.  
  57. If 'TypDigit' is the  type of a digit and 'TypTwoDigits'  is an  unsigned
  58. integer type twice as wide, I can write
  59.  
  60.     TypDigit            a;
  61.     TypDigit            b;
  62.     TypTwoDigits        product
  63.     ...
  64.     product = (TypTwoDigits)a * (TypTwoDigits)b;
  65.  
  66. The  casts  are necessary,  because  otherwise  an  ANSI  compiler  where
  67. 'sizeof(unsigned int)  =  sizeof(TypDigit)' would only compute  the lower
  68. digit of the product and set the upper digit to 0.
  69.  
  70. Now I am not complaining that  those casts are necessary or that a stupid
  71. compiler  might generate  a 'TypTwoDigits'-multiplication instruction.  I
  72. understand that a compiler with a clever optimizer is allowed to generate
  73. a mixed  size multiplication instruction.
  74.  
  75. So far so good.  This satisfies requirements 1) and 2).  Unfortunately it
  76. does not satisfy requirement 3).  Here is why.
  77.  
  78. The largest unsigned integer type which ANSI gives me is 'unsigned long'.
  79. With almost all processors and C compilers I know 'unsigned long' is just
  80. as wide as an register (usually this means 32 bit,  but  not  necessarily
  81. so).  Please don't tell me that I should buy a C compiler where 'unsigned
  82. long'  is  twice  as  wide as an register, unless you can tell me which C
  83. compilers for 80386, MIPS, and Sparc systems have this feature.
  84.  
  85. Now most modern processors *do* have  an instruction that  multiplies two
  86. registers  and puts the  result into a register pair or a set of  special
  87. registers.   Here  is  a  short  list (I  also  have  a  list  with  more
  88. information, which I can send on request).
  89.  
  90.     32 bit processors that have 32x32->64 instructions:
  91.         AMD 29000, AMD 29050, DEC Alpha 21064,  HP PA-RISC 1.1,
  92.         IBM RS6000, Transputer T9000, Intel i[34]86, Intel 960CA/CF,
  93.         MIPS R[2346]000, Motorola 680[234]0, Motorola 88110,
  94.         Sparc V7 (multiply step), Sparc V8
  95.  
  96.     32 bit processors that have no 32x32->64 instruction:
  97.         ARM [23], HP PA-RISC 1.0, Intel i860,
  98.         Motorola 680[01]0, Motorola 881000
  99.  
  100.     64 bit processors that have 64x64->128 instructions:
  101.         DEC Alpha 21064, MIPS R4000
  102.  
  103. In almost  all cases the  32x32->64 instructions are about as fast as the
  104. 16x16->32  instructions (in fact in most cases the  32x32->64 instruction
  105. will be used for 16x16->32 multiplications as well).
  106.  
  107. That means: *if I  could  use the 32x32->64 instruction  I could make  my
  108. multiplication run four times as fast*. This is because I could then make
  109. 'TypDigit' twice  as wide,  implying that my integers  have only  half as
  110. many digits, speeding up the multiplication by a factor of four.  (For 64
  111. bit microprocessors  the same applies,  one could make the digits 64 bits
  112. wide and win a factor of four over a portable implementation that uses 32
  113. bit digits).
  114.  
  115. This is *not* idle  speculation.  By using  small assembler functions one
  116. can show that this factor can really be obtained.
  117.  
  118. However,  I  cannot  use  the  32x32->64 multiplication,  because  the  C
  119. compiler  provides no  unsigned integer  type  to  hold  the  result.  To
  120. convince me otherwise, do the following
  121.  
  122.     a)  pick a processor of the above list  of  32 bit  processors  with
  123.         32x32->64 instruction
  124.  
  125.     b)  pick a compiler
  126.  
  127.     c)  write a piece of ANSI conforming code that multiplies two  32 bit
  128.         unsigned integers and produces a 64 bit result
  129.  
  130.     d)  show me the assembler output that uses only one  32x32->64  mult.
  131.         instruction
  132.  
  133. If you can do this, I may think about retracting the following statement.
  134.  
  135. *For any  of  the processors  HP  PA-RISC  1.1, MIPS  R[234]000, Motorola
  136. 680[234]0, Sparc V7&V8 there is an assembler function that multiplies two
  137. large integers  at least twice as fast  as  any  ANSI  conforming  C code
  138. compiled with any widely available compiler.*
  139.  
  140. This is actually a weak statement.  The strong statement would contain  a
  141. larger list  of processors and replace the  factor  of two with something
  142. between 3 and 4.
  143.  
  144. Of course if one  is  willing to drop requirement 3),  one has a lot more
  145. options.  One could  use 'asm' code (this is what  GNU  GMP does with GNU
  146. CC), 'long  long' integer types, or use a small assembler kernel (this is
  147. what BigNum, PARI, and my arithmetic do).
  148.  
  149. Martin.
  150.  
  151. -- .- .-. - .. -.  .-.. --- ...- . ...  .- -. -. .. -.- .-
  152. Martin Sch"onert,   Martin.Schoenert@Math.RWTH-Aachen.DE,  +49 241 804551
  153. Lehrstuhl D f"ur Mathematik, Templergraben 64, RWTH, D 51 Aachen, Germany
  154.  
  155.