News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Floating point arithmetic question

Started by Lonewolff, April 16, 2018, 08:20:24 PM

Previous topic - Next topic

RuiLoureiro

Quote from: jj2007 on April 17, 2018, 10:55:42 PM
Quote from: RuiLoureiro on April 17, 2018, 10:41:22 PMfstp  st should be used, it is faster. It removes the current st(0) when we dont need it.

Btw there is also fincstp, which at first sight has the same effect. But try a simple fldpi afterwards, and you'll see the difference. Olly has a section with the FPU regs, you must scroll down a little bit the upper right pane to see it.
Ok Jochen. I dont know where i have Olly in this computer. I rarely use it. LoneWolff may do this to learn.
            What i want to say to LoneWolff is this: generally, we use fstp st to remove st(0) when we dont need it.

Lonewolff

Yeah, the fstp resultX call was just to get rid of the value. I'll swap out the command now that that I know about it.

Thanks guys! Awesome information as always  8)

RuiLoureiro

Quote from: Lonewolff on April 18, 2018, 07:47:06 AM
Yeah, the fstp resultX call was just to get rid of the value. I'll swap out the command now that that I know about it.

Thanks guys! Awesome information as always  8)
Good luck  :t

Lonewolff

Quote from: RuiLoureiro on April 18, 2018, 08:03:43 AM
Good luck  :t

Thanks Rui  :biggrin:

There was a measurable performance increase with the fstp st method.


fld number
fptan
fstp st
fstp result



But fincstp gave me a NaN result.


fld number
fptan
fincstp
fstp result

Siekmanski

Creative coders use backward thinking techniques as a strategy.

Lonewolff


fld number
fptan
ffree st(0)
fstp result


That one gives me a Nan result also  :(

Lonewolff

Was just reading about the fincstp method.

http://qcd.phys.cmu.edu/QCDcluster/intel/vtune/reference/vc98.htm

This operation is not equivalent to popping the stack, because the tag for the previous top-of-stack register is not marked empty.

raymond

Quote from: Lonewolff on April 18, 2018, 08:26:21 AM

fld number
fptan
ffree st(0)
fstp result


That one gives me a Nan result also  :(

Let's see if you can use your skills to find out in the tutorial why you are getting that result. ;)
Whenever you assume something, you risk being wrong half the time.
http://www.ray.masmcode.com

Lonewolff

Quote from: raymond on April 18, 2018, 10:18:38 AM
Quote from: Lonewolff on April 18, 2018, 08:26:21 AM

fld number
fptan
ffree st(0)
fstp result


That one gives me a Nan result also  :(

Let's see if you can use your skills to find out in the tutorial why you are getting that result. ;)

Ha! Got me again.

It's that double pop thing again. Had only just woken up when I tried it out.  :t

jj2007

Quote from: Siekmanski on April 18, 2018, 08:22:52 AM
Try this one,
ffree   st(0)

That instruction is about as rare as fincstp, and for the same reason :P

Quote from: Lonewolff on April 18, 2018, 08:34:38 AMThis operation is not equivalent to popping the stack, because the tag for the previous top-of-stack register is not marked empty.

Exactly :t

The point here is: fincstp rotates ST(0) into ST(7). If ST(7) is not empty, i.e. it carries a value, then any attempt to load ST(0) will fail.

In practice, you will never see ffree ST(0) or fincstp, but you will often see
fstp st ; pop ST, clear ST(7)
ffree ST(7) ; clear ST(7)
fxch ; to get ST(1), exchange ST(0), ST(1)

Lonewolff

Quote from: jj2007 on April 18, 2018, 11:21:32 AM
Quote from: Siekmanski on April 18, 2018, 08:22:52 AM
Try this one,
ffree   st(0)

That instruction is about as rare as fincstp, and for the same reason :P

I found that using that instruction, I had to fincstp anyway to get the right result. Which negated any performance gains.

Seems that fstp st has given the best performance so far.

RuiLoureiro

Hi LoneWolff,
                   fstp    st  is the same as fstp  st(0).
                   But there are cases where we want to remove st(1) ...
                   In these cases we use  fstp  st(1) ...

                   In some cases, after one FPU instruction, we add this code to detect an error:

                   fstsw      ax         ; store Status Word register to AX register
                   fwait
                   shr         ax, 1     ; move bit 0 to carry flag
                   jc           _iserror
                   ; go on, here not error
                   ...
                   ; exit here without error


_iserror:     fstp         st     ; remove st(0)
                  fclex                ; clear all bits in the status word register -> new instruction, new error ?
                  ; exit here with an error message

Lonewolff

Hey guys,

I thought I'd ask this in this topic rather than create a new one, as it is still a FP question.

Is there a more efficient way of writing this? I regards to the final 'fstp' call.

This code works fine, just wondering if it is optimal.

fld fP ; farPlane / (farPlane - nearPlane)
fld nP
fsub
fld fP
fdiv st(0),st(1)
fstp _res
mov ecx, _res
mov [eax+40], ecx ; Store result in _33
fstp _res ; Clear the last value from the FP stack


If I don't call the final line, a value gets left on the FP stack. I could call 'fpinit' but that is a very slow call.

Just wondering if I am going about this the right way.

Thanks again  8)


[edit]
Actually, thinking about it, I probably just need to play with the order of operation.


[edit2]
Yep worked well. And one line less.


fld fP ; farPlane / (farPlane - nearPlane)
fld fP
fld nP
fsub
fdiv
fstp _res
mov ecx, _res
mov [eax+40], ecx ; Store result in _33

Siekmanski

   fld fp            ; farPlane / (farPlane - nearPlane)
   fld st
   fld rp
   fsubp
   fdivp
   fstp real4 ptr [eax+40]

:biggrin:
Creative coders use backward thinking techniques as a strategy.

Lonewolff

Nice!

Even better  :eusa_clap:

[edit]
Hang on. It says invalid operands on fsubp and fdivp.  :P

Were those two lines a typo?