Re: R-alpha: R 0.12 alpha: problem with qt()

Peter Dalgaard BSA (pd@kubism.ku.dk)
07 Nov 1996 11:10:19 +0100


To: R-testers@stat.math.ethz.ch
Subject: Re: R-alpha: R 0.12 alpha: problem with qt()
From: Peter Dalgaard BSA <pd@kubism.ku.dk>
Date: 07 Nov 1996 11:10:19 +0100
In-Reply-To: Douglas Bates's message of Wed, 6 Nov 96 14:21 CST
Message-Id: <x2k9ryqkqc.fsf@bush.kubism.ku.dk>

Douglas Bates <bates@stat.wisc.edu> writes:

> If you do a comparison of two "double" values from memory, they will
> be converted from 64 bits to 80 bits when they are loaded into FP
> registers then compared.  (In fact, for equality they may actually be
> compared as bit patterns.)  Of course they will be equal if they matched
> as 64 bit quantities.  If you compare two values stored in registers
> directly after their calculation they will be equal only if they match
> as 80 bit quantities.
> 
> The reason that your debugging print statements changed the behaviour
> is because they caused different usage of the floating point registers
> in the critical section of the calculation.

Yep. I know.
 
> There is actually a compiler option to get around this problem
> 
>  `-ffloat-store'

-- which is a really terrible way of fixing things, since it takes
essentially all efficiency out of the floating point code, especially
in view of the fact that things work fine if one refrains from
optimizing. 

However, you are probably right about the cause. In particular, code
like this is dangerous:

                if (tx == xinbta)
                        goto L10;
                xinbta = tx;
  
Never trust equality in floating point arithmetic! If tx is in a
register and xinbta in memory, the test will fail but the assignment
won't change xinbta - and around and around and around and around and
we goooooo again....

Lets see: The optimized code for this bit is:

        fldl -104(%ebp) 
        fucomp %st(1)
        fnstsw %ax
        andb $69,%ah
        cmpb $64,%ah
        je .L54
        fstpl -104(%ebp)

whereas the unoptimized is

        fldl -108(%ebp)
        fldl -140(%ebp)
        fucompp
        fnstsw %ax
        andb $68,%ah
        xorb $64,%ah
        jne .L32
        jmp .L29
        .align 16
.L32:
        movl -108(%ebp),%eax
        movl %eax,-140(%ebp)
        movl -104(%ebp),%eax
        movl %eax,-136(%ebp)

Exactly as suspected. In one case, tx is coming from the FPU (%st(1))
and in the other from the stack (-108(%ebp)). 

I'll see if I can come up with a better solution than -ffloat-store.

-- 
   O__  ---- Peter Dalgaard             Blegdamsvej 3  
  c/ /'_ --- Dept. of Biostatistics     2200 Cph. N   
 (*) \(*) -- University of Copenhagen   Denmark      Ph: (+45) 35327918
~~~~~~~~~~ - (p.dalgaard@biostat.ku.dk)             FAX: (+45) 35327907
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
r-testers mailing list -- To (un)subscribe, send
subscribe	or	unsubscribe
(in the "body", not the subject !)  To: r-testers-request@stat.math.ethz.ch
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-