Article View: comp.arch
Article #11027Re: how to advocate new software/hardware features (Re: Hardware Support for Numeric Algorithms)
From: Martin Schoenert
Date: Tue, 17 Nov 1992 10:21
Date: Tue, 17 Nov 1992 10:21
167 lines
8159 bytes
8159 bytes
Bob Silverman wrote in his article:
Quite a few modern microprocessors have hardware to do 32 x 32 bit
multiplies and 64 bit / 32 bit divides. I know of no HLL that will
allow me to write code to access these instructions. For example,
suppose I want to compute A*B/C exactly, where A,B, C are 32 bit
ints and C > A and C > B. How do I do this in a HLL ?
Alan Watson responded in his article:
Not that I wish to defend C, but a good compiler should be able to
eliminate unnecessary casts and use mixed 32/64-bit arithmetic in the
following expressions:
long l, n, m;
int i, j, k;
l = (long) i * (long) j; /* emit 32x32 -> 64 */
n = m / i; /* emit 64/32 -> 64 */
by use of the `as if' rule. Perhaps there is a subtlety I have
missed. I agree that the casts are a nuisance, and one can argue that
C's default promotions are perhaps not the best choice, but in these
cases the language does provide the degree of control that Silverman
requires.
This of course assumes that 'long' is 64 bits wide. On most commercial
systems this just isn't the case. If 'sizeof(long) = sizeof(int) = 4'
you only get the lower half of the product this way (and the upper half
is much more difficult to get).
Besides, I have collected some information about the multiplication
instructions of modern micro processors. From this it appears to me that
on those systems where 'sizeof(long)' might be 8 (64 bits) you also have
a 64x64 -> 128 instruction (or short sequence of instructions). And then
you loose again because you cannot get at the upper half of such a 128
bit product.
Thomas Breuel responded in his article:
Well, then you simply haven't looked very far. Many implementations
of HLL let you access those instructions in a variety of ways.
(1) Implementations like GNU C/C++ and implementations of CommonLisp
and Scheme often have very sophisticated and efficient assembly
language interfaces. Of course, those interfaces are not portable,
but neither is the assembly language (I myself would like to see
vendors standardize on the GNU C/C++ assembly language interface).
Yes that is true, and I know of at least one large integer arithmetic
which uses GNU C to get at the powerful multiplication instructions.
However, the assembler interface is not part of the definition of C
(neither ANSI or K&R say something about it). So it is true that the
*language* does allow you to do this (even though special
*implementations* might).
Thomas Breuel continues:
(3) Many programming languages let you declare 32 and 64bit
integers explicitly and good compilers will select the right
instruction to go with the types (Ada and CommonLisp are
among those languages).
Even the C language has provisions for just the case that you are
concerned with in the case of 16bit integers, 32bit longs:
int a = ...;
int b = ...;
int c = ...;
long product = a*b;
int result = product/c;
In fact, on some machines, int is 32bit and long is 64bit,
so this code will do what you want.
Ahh, but the 16x16->32 bit multiplication is not as good. Suppose that I
want to multiply two large integers, each 32 bytes long. Using 16x16->32
bit multiplication I need 256 such instructions. Using 32x32->64 bit
multiplication I only need 64 such instructions. Since on most modern
processors both instructions take about the same amount of time the
latter is about 4 times as fast. (If you have an application that runs
for MIPS years, a factor of 4 is quite a big deal ;-)
Thomas Breuel continues:
Furthermore, C is being extended to allow access to 64bit types,
so that you can write:
int a = ...;
int b = ...;
long long product = a*b;
int result = product/c;
This may be so, but it isn't really relevant. Bob talked about
*languages*, you talk about *implementation* or possible *extension*.
This is not the same thing.
Herman Rubin writes in his article:
In addition, this has architectural implications. Hardware
designers seem to avoid asking users what instructions they want in
hardware, but look at the current HLLs. Having nxn ->2n [32bit x
32bit multiplication yielding a 64bit result] in the language, and
2n/n in the language, is far more likely to keep it in the
architecture than Bob using it in his programs.
Well I don't know. From my information about the multiplication
instructions it appears that almost all modern processors have nxn->2n
instructions, even though they *cannot* be used from C (which seems to be
the HLL that architects are most concerned with).
Herman Rubin writes in another article:
>(3) Many programming languages let you declare 32 and 64bit
> integers explicitly and good compilers will select the right
> instruction to go with the types (Ada and CommonLisp are
> among those languages).
> Even the C language has provisions for just the case that you are
> concerned with in the case of 16bit integers, 32bit longs:
> int a = ...;
> int b = ...;
> int c = ...;
> long product = a*b;
> int result = product/c;
As I read the language description, types are cast either before
or after the operation. I know of no operations in the C language
which explicitly allow for different types of arguments/results
except for comparisons, with Boolean results. And those Booleans
are not very flexible. As Bob Silverman wrote, he would like to
use a different operation symbol for the situation.
Let us use a slightly different example (so that we avoid the issues of
overflow and sign handling).
unsigned short a, b; /* assume 16 bits */
unsigned long c; /* assume 32 bits */
c = (unsigned long) a * (unsigned long) b;
The ANSI definition specifies that the result (c) shall be the value one
gets when one does the following
extend a to 32 bits
extend b to 32 bits
multiply a and b to give a 64 bit result with a 32x32->64 instruction
shorten the result to 32 bits
However, ANSI does *not* specify how the produced object code shall
obtain this result. (As far as ANSI is concerned it would be all right
to e-mail the operands to another machine, have the other machine compute
the result and e-mail it back ;-) So because the following sequence would
give the same result as the one above, it would be absolutly legal for an
ANSI compiler to produce this code
multiply a and b to give a 32 bit result with a 16x16->32 instruction
And yes, I have seen compilers produce such code. (It doesn't help us of
course, because we really want to use the 32x32->64 bit instruction and
are usually missing the 64 bit integer type to hold the result).
Martin.
-- .- .-. - .. -. .-.. --- ...- . ... .- -. -. .. -.- .-
Martin Sch"onert, Martin.Schoenert@Math.RWTH-Aachen.DE, +49 241 804551
Lehrstuhl D f"ur Mathematik, Templergraben 64, RWTH, D 51 Aachen, Germany
Technical Details
Message-ID:
<martin.721995695@bert>Path:
arc1-ca.pugleaf.net!sparky!uunet!zaphod.mps.ohio-state.edu!cs.utexas.edu!usc!sol.ctr.columbia.edu!ira.uka.de!math.fu-berlin.de!unidui!rrz.uni-koeln.de!Germany.EU.net!Urmel.Informatik.RWTH-Aachen.DE!martinReferences:
<TMB.92Nov14145619@pollux.idiap.ch> <Bxq7y0.IJ@mentor.cc.purdue.edu> <mwm.2n6z@contessa.palo-alto.ca.us> <Bxr8vG.IpI@mentor.cc.purdue.edu>Show Full Headers
Complete Article Headers
Newsgroups: comp.arch,comp.lang.misc Path: arc1-ca.pugleaf.net!sparky!uunet!zaphod.mps.ohio-state.edu!cs.utexas.edu!usc!sol.ctr.columbia.edu!ira.uka.de!math.fu-berlin.de!unidui!rrz.uni-koeln.de!Germany.EU.net!Urmel.Informatik.RWTH-Aachen.DE!martin From: martin@math.rwth-aachen.de ( Martin Schoenert) Subject: Re: how to advocate new software/hardware features (Re: Hardware Support for Numeric Algorithms) Message-ID: <martin.721995695@bert> Sender: news@Urmel.Informatik.RWTH-Aachen.DE (Newsfiles Owner) Nntp-Posting-Host: bert.math.rwth-aachen.de Organization: Rechnerbetrieb Informatik / RWTH Aachen 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> Date: 17 Nov 92 10:21:35 GMT Lines: 168