News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Fpu is very slow....

Started by Airam, August 09, 2009, 11:23:23 PM

Previous topic - Next topic

Airam

Hello!!
I've got a problem with the FPU and the CPU. I have a code similar like that:

procedure proc
  invoke DoSthgWithTheFPU
  invoke FillAListViewWithTheResusltsObtainedBefore
  ret
procedure endp

So when i invoke the DoSthgWithTheFPU procedure I do several calculations with the FPU and I fill some arrays with real10 numbers. Then I invoke FillAListViewWithTheResusltsObtainedBefore procedure where i read the values of the arrays calculated before and convert them to decimal numbers. Once converted the values i add them to a ListView control (in the second procedure).

If i give time between the procedures, for example using a msgbox:
procedure proc
  invoke DoSthgWithTheFPU
  Invoke MessageBox, NULL, Addr text, 0, MB_OK Or MB_ICONERROR
  invoke FillAListViewWithTheResusltsObtainedBefore
  ret
procedure endp

Everything goes perfect, but If i omit the massagebox sentence, i can't see anything at the List View.
How do I give some time between the two procedures?

Thanks in advance.

jj2007

Tried to replace the MessageBox with invoke Sleep, 100?

dedndave

you might even try invoke Sleep,0

JayPee

Try using the fwait instruction to prevent the cpu from processing further instructions while the fpu is processing
Greetings From New Zealand
(Land of the Long White Cloud)

dedndave

yah - what JayPee said - lol

Airam

Thanks everybody for answering me.
invoke sleep, 100 doesn't work. It seems it waits but the list view isn't filled.
I have put lots of fwaits throughtout the fpu instructions but it still doesn't work.
By the way, the two invokes are called when i select an item on the menu.


jj2007

Quote from: Airam on August 10, 2009, 08:11:23 AM
Thanks everybody for answering me.
invoke sleep, 100 doesn't work. It seems it waits but the list view isn't filled.
I have put lots of fwaits throughtout the fpu instructions but it still doesn't work.
By the way, the two invokes are called when i select an item on the menu.


Raymond says MessageBox is one of the API's that destroy FPU content. Interesting that in your case it helps... ::)
Try to strip down your code to the essential bits, and then post the complete source.

dedndave

QuoteRaymond says MessageBox is one of the API's that destroy FPU content. Interesting that in your case it helps...
coincidence, eh ? - Ray was just saying that the other day
it may be because of the fwait thing
that makes me consider - sometimes, it may be a good idea to put fwait at the end of a proc

Airam

Hi again!

May be it is related to the fpu stack because I have tested it by sending a message to the status bar instead of displaying a msgbox and it works.
The code is something like this:
procedure proc
  invoke DoSthgWithTheFPU
  Invoke SendMessage, hStatus, SB_SETTEXT, 0, Addr ConvO
  invoke FillAListViewWithTheResusltsObtainedBefore
  ret
procedure endp

This is also another API (the StatusBar, I suppose). I don't think it's a problem of fwait, because i actually have a lot. I also think that is a problem of time, i mean: if i calculate all array values when the program start and then i push a button, it is invoked the second procedure and it is showed the result in the ListView.

P.D: If you want my source code I can send it to your e-mail. I can't post it here because it's a university task.

Astro

QuoteI can't post it here because it's a university task.
Ahh - homework...

Quote9. The NO HOMEWORK Rule.
The forum is a technical help forum for assembler language programmers, it will not be used as a location for grovelling to get someone to do your homework. Members who are learning assembler programming at school or similar are welcome but they must do their own work. In this context they will receive assistance if they need it but any dumping of problems in the forum will be removed. Also note that 16 bit DOS code will be moved to the 16 bit DOS forum as this forum is primarily a 32 bit Windows assembler forum.

Where I can, I would be happy to try and explain why you're seeing what you are seeing in terms of behavior, but after having been stung a few months ago in another forum over a task that turned out to be homework that I spent quite some time sorting out to explain (and in the process, solving the very point of the homework), I'm not very inclined to help at all. Nothing personal.

Is the point of this work to figure out why it is doing this? Maybe a homework in program flow/design or something?

If you can be totally open about the purpose of the exercise, I'll take a look.

Best regards,
Astro.

Airam

Of course, I understand the rule, Astro. It's logical not to do the homework of other people. But I'm not asking anybody to do my homework, I'm just asking a very specific question about something that doesn't seem very logical to me. I just want an explanation of what happens here. I mean, why does my code works when I use an invoke to an api and if I omit it, why it does not work.

The task that i have to do is just to calcule a thousand values of J0(B) Bessel Function.
But in order to learn more about assembler i decided to create also a Win32 application with a listview, dialogs, ...., and also paint the function. This is not part of the task, but I'm having fun doing that.
In short, I'm doing an unofficial thing :wink


Astro

No probs! Sorry if I seemed hostile.

I think you can attach files to PMs, so send me a PM with your code and I'll take a look.

I'm intrigued as to why 'invoke' vs. 'call' has different effects.

If you don't have one, get a debugger. http://en.wikipedia.org/wiki/Ollydbg is excellent.

Best regards,
Astro.

MichaelW

Airam,

Are you sure that your FPU code is not generating exceptions? This can have a very large effect on the execution time. In the initialized state the FPU handles exceptions internally, but you can change this behavior with something like this:


;-----------------------------------------
; Bit values for the FPU interrupt masks.
;-----------------------------------------

PM equ 32   ; precision mask       
UM equ 16   ; underflow mask
OM equ 8    ; overflow mask
ZM equ 4    ; zero-divide mask
DM equ 2    ; denormalized operand mask
IM equ 1    ; invalid operation mask

;--------------------------------------------------------
; This macro selectively clears the FPU interrupt masks.
; Example usage: clearintmasks IM or ZM or OM
;--------------------------------------------------------

clearintmasks MACRO maskbits
    push eax
    fstcw [esp]   
    fwait
    pop eax
    and ax, NOT (maskbits) ; parentheses required for proper operation
    push eax
    fldcw [esp]
    pop eax
ENDM

eschew obfuscation

dedndave

i bumped into that one the other day, Michael - lol
i was missing a ffree, so the fpu stack got full - slows things WAY down

raymond

This does sound VERY weird.

"invoke" is a call instruction and the next instruction should not be performed until the return from the call which would set the EIP to it. An intermediate call to some API should not have any effect on whatever is stored in memory by the first call, on which basis the call to display data in the list box should rely.

I would also volunteer to have a look at your code if you don't mind.

BTW, masking the exception bits in the Control Word means that you have to include some code to take care yourself of such exceptions.  That could be even slower than letting the system taking care of them. Unless you strongly disagree with how the system handles them, it's not worth the effort. You're better off checking the exception flags in the Status Word whenever you would suspect the possibility of some exception and take action at that time (such as aborting further computations, displaying a message box, etc.).
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com