T.R | Title | User | Personal Name | Date | Lines |
---|
1541.1 | | DCETHD::BUTENHOF | Dave Butenhof, DECthreads | Thu May 08 1997 15:07 | 14 |
| Well, as you know, IEEE floating point calculations are 4 times as fast as
the equivalent calculation in VAX floating point -- so of course the delays
take only 1/4 as much time!
Your analysis is probably correct. The CMA libraries were (and still are)
built with the default floating point format. So, if the default is VAX
floating point, that's what you get. Since this is not a bug, (at worst it's
a restriction), and since the CMA interface is now obsolete, it's unlikely
that this will change. (It's certainly not going to be changed on 6.2.)
This doesn't affect pthreads -- either the DCE thread interface on 6.2 or the
POSIX threads interfaces -- because they have no floating point arguments.
/dave
|
1541.2 | | CSC32::J_HENSON | Don't get even, get ahead! | Fri May 09 1997 11:21 | 7 |
| >> <<< Note 1541.1 by DCETHD::BUTENHOF "Dave Butenhof, DECthreads" >>>
>>Your analysis is probably correct. The CMA libraries were (and still are)
Thanks,
Jerry
|
1541.3 | | SPECXN::DERAMO | Dan D'Eramo | Fri May 09 1997 17:42 | 99 |
| Every C interface that uses floating point runs into this
problem. Search alps$scratch:[LST_Titles]ucx.notes for
xdr_float or xdr_double or see C950320-9056 for examples.
There are various solutions. For example, look how DEC C
handles printf. It needs to work differently depending on
whether double has type D_Float, G_Float, or T_Float and
whether long double is 64 bits or 128 bits. So depending on
the qualifiers you use in your CC command, the name printf
gets "prefixed" or "mangled" to any of
DECC$DPRINTF
DECC$GPRINTF
DECC$TPRINTF
DECC$DXPRINTF
DECC$GXPRINTF
DECC$TXPRINTF
so at run-time the correct routine is called for the CC
command line qualifiers that you used.
A second example is LIB$WAIT, which is documented as taking an
F_Float argument passed by reference. It is up to you the
programmer to pass the address of an F_Float, meaning that if
you compile with CC/FLOAT=IEEE_FLOAT then you cannot just do
float seconds = 10.0;
int status = lib$wait(&float);
Instead, you have to put an F_Float bit pattern together in a
longword and pass the address of that.
A third example is UCX XDR's xdr_float and xdr_double.
The UCX V4.0 header file UCX$RPC:XDR.H on OpenVMS Alpha
contains:
/*
** Select the appropriate XDR floating and double routines
** based upon the selection of the floating point format at
** compile time.
*/
#if (__D_FLOAT == 1)
#define xdr_double xdr_double_D
#endif
#if (__G_FLOAT == 1 || CC$gfloat == 1)
#define xdr_double xdr_double_G
#endif
#if (__IEEE_FLOAT == 1)
#define xdr_float xdr_float_S
#define xdr_double xdr_double_T
#endif
.
.
.
Now cma_delay(float) is an interesting case. On OpenVMS VAX,
the arglist has to look like
ap: 1
ap+4: F_Float value
and as long as the prototype cma_delay(float) is seen first
both VAX C and DEC C will set that up whether compiled with
D_Float doubles or F_Float doubles. Without the prototype
in scope the arglist looks like
ap: 2
ap+4: first longword of (double) value
ap+8: second longword of (double) value
where (double) means D_Float or G_Float depending on how the
program actually was compiled. (If it was D_Float the call
could still actually work.)
You can fake this out by calling an unprototyped cma_delay
or cma$delay with an int argument that had the correct bit
pattern of the F_Float representation of the desired delay.
On OpenVMS Alpha it is more difficult because you have to get
the correct bit F_Float register representation bit pattern
into floating point register F16. You can do that in macro-64
or in DEC C compiled as D_Float or G_Float as long as the
cma_delay(float) prototype has been seen. Without the
prototype D_Float might work, the others almost certainly
won't.
If the argument had been passed by reference you could put the
F_Float representation together in a longword (of whatever
type) and pass its address--see LIB$WAIT above. But the
argument to cma_delay is passed by value.
I think the only thing that will work on OpenVMS Alpha is to
prototype cma_delay as taking an __f_float argument, but that
is an undocumented type.
Dan
|
1541.4 | By-value in registers ought to work, usually | WIBBIN::NOYCE | Pulling weeds, pickin' stones | Mon May 12 1997 11:25 | 18 |
| > On OpenVMS Alpha it is more difficult because you have to get
> the correct bit F_Float register representation bit pattern
> into floating point register F16. You can do that in macro-64
> or in DEC C compiled as D_Float or G_Float as long as the
> cma_delay(float) prototype has been seen. Without the
> prototype D_Float might work, the others almost certainly
> won't.
Actually, since register representations are basically always G_float,
this can approximately work. If you're passing an integer less than
about 15 million, there should be no problem -- the register representation
is the same for F_float and G_float. (It's different, by a factor of 4,
for IEEE types). Passing larger integers, or fractional values, has some
risk that you'll produce a value in a register that has nonzero bits
beyond the 24th fraction bit -- if the called routine applies F_float
operations to such a value the results are undefined. If your fraction
can be exactly represented in F_float (for example, you computed the
value in F_float before passing it) there is no problem.
|