[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference clt::cma

Title:DECthreads Conference
Moderator:PTHRED::MARYSTEON
Created:Mon May 14 1990
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:1553
Total number of notes:9541

1541.0. "IEEE floats on OVMS/Alpha?" by CSC32::J_HENSON (Don't get even, get ahead!) Thu May 08 1997 12:26

dec c, openvms v6.2, alpha

A customer is reporting that when he compiles with /float=ieee, calls
to cma_delay complete in about 1/4 the time as they do when he compiles
with floating point defaults.

My guess is that the cma (and probably pthreads) routines that accept 
floating point values are interpreting the values as f_float (single
precision) or g_float (double precison) numbers, and thus mis-interpreting
the number he is using.  I told him to use cvt$convert_float to
convert his ieee number to a vax_f and pass the converted value.

Is this a correct assumption?  If not, what is going on in this case?
If so, is there a better solution than using cvt$convert_float?

Thanks,

Jerry

P.S.  I did a dir/title=delay and dir/title=ieee to see if this issue
has already been discussed, but didn't find anything that looked
relevant.
T.RTitleUserPersonal
Name
DateLines
1541.1DCETHD::BUTENHOFDave Butenhof, DECthreadsThu May 08 1997 15:0714
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.2CSC32::J_HENSONDon't get even, get ahead!Fri May 09 1997 11:217
>>       <<< Note 1541.1 by DCETHD::BUTENHOF "Dave Butenhof, DECthreads" >>>

>>Your analysis is probably correct. The CMA libraries were (and still are)

Thanks,

Jerry
1541.3SPECXN::DERAMODan D&#039;EramoFri May 09 1997 17:4299
        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.4By-value in registers ought to work, usuallyWIBBIN::NOYCEPulling weeds, pickin&#039; stonesMon May 12 1997 11:2518
>        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.