News:

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

CMOV Macro ?

Started by Ficko, August 07, 2009, 07:52:48 PM

Previous topic - Next topic

Ficko

Do somebody knows where can I find some kind of "CMOV" macro.
- I am to lazy to write one if allready exists - :toothy

Should be something like:

CMOV (eax == ebx)


cmp eax, ebx
cmove eax, ebx


of curse that's the easy part it should be able to handle this:

CMOV (sdword ptr eax > ebx)
as well. :bg

Thanks,
Ficko

Jimg

It's going to be pretty tough since < and > are macro variable delimiters.

hutch--

Arrrrgh, whats wrong with CMOV ?
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

GregL

QuoteArrrrgh, whats wrong with CMOV ?

:lol  That's exactly what I was going to say.  Why not just use CMOV?



donkey

I have a great macro:

MOV(mem32,reg32) MACRO
    push reg32
    pop eax
    push offset mem32
    pop edi
    stosd
ENDMACRO
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

dedndave

very nice Edgar   :U
how about ...

  push reg32
  pop  mem32

i have been poking around - reading about cmov's
one of the articles i read said you may be better off to use the traditional cmp/branch code
according to the article, the branch will be predicted and run faster, overall
the cmov cannot be predicted, and thus, may take longer
the article did say, that in cases where the outcome of the conditional is completely random, cmov may have a slight advantage due to size
they said that on a P4, the branch will typically be better
on newer cpu's, the difference will be more or less negligible

jj2007

Quote from: dedndave on August 08, 2009, 10:44:25 AM
very nice Edgar   :U
how about ...

  push reg32
  pop  mem32


How good to have a long-time macro hater finally on our side! But Edgar trashes edi :naughty:

Quote
i have been poking around - reading about cmov's
one of the articles i read said you may be better off to use the traditional cmp/branch code
according to the article, the branch will be predicted and run faster, overall
the cmov cannot be predicted, and thus, may take longer
the article did say, that in cases where the outcome of the conditional is completely random, cmov may have a slight advantage due to size
they said that on a P4, the branch will typically be better
on newer cpu's, the difference will be more or less negligible

The Mozilla guys say cmov is a winner, sometimes.

P.S.: Since this is the Campus: attention, the MOV macro is an insider joke... :wink

Vortex

Quote from: Greg on August 08, 2009, 12:49:23 AM
QuoteArrrrgh, whats wrong with CMOV ?

:lol  That's exactly what I was going to say.  Why not just use CMOV?

Possibly, he could have an old processor not supporting the CMOV instruction.

dedndave

with regard to designing code around the P4, i would say, there are a lot of P4's out there
of course, intel and amd want you to buy a newer one, so they'll account for smaller target percentages over time
as Erol said, the cmp/branch code works on more older processors
i am guessing the random/non-random thing leans toward the non-random
most branching is somewhat predictable
it's harder to predict the future - cpu architecture is likely to improve to the point that there is little difference
in days of old, if you could eliminate a cmp/branch with 4 fast lines (mov reg,reg etc), it was probably better not to branch
i am a little surprised to see just how fast conditional branches are, nowdays
an extreme example of the same thing is all the kinks we use to multiply and divide - lol
at some point intel and amd are going to figure out that a static gate array can do most of the work
then, div and mul will be under 10 clock cycles and we'll have all this code that has long shl/add sequences - lol

jj2007

cmov seems faster for "alternating" tests:

mov ecx, 1000
.Repeat
test ecx, 1
cmove eax, ecx
dec ecx
.Until Zero?


For a test ecx, ecx, it is slower:
2621    cycles for cmove, test ecx, 1
4016    cycles for je, test ecx, 1

2624    cycles for cmove, test ecx, ecx
2036    cycles for je, test ecx, ecx


Full code below.
.nolist
include \masm32\include\masm32rt.inc
.686
include \masm32\macros\timers.asm
buffersize = 10000 ; don't go higher than 100000, ml.exe would slow down
LOOP_COUNT = buffersize ; in this case; otherwise, 1000000 would be a typical value

.data?
dummy db 8 dup(?)
buffer dd buffersize dup(?)

.code
start:
REPEAT 2
counter_begin LOOP_COUNT, HIGH_PRIORITY_CLASS
mov ecx, 1000
.Repeat
test ecx, 1
cmove eax, ecx
dec ecx
.Until Zero?
counter_end
print str$(eax), 9, "cycles for cmove, test ecx, 1", 13, 10

counter_begin LOOP_COUNT, HIGH_PRIORITY_CLASS
mov ecx, 1000
.Repeat
test ecx, 1
jne @F
mov eax, ecx
@@:
dec ecx
.Until Zero?
counter_end
print str$(eax), 9, "cycles for je, test ecx, 1", 13, 10, 10

counter_begin LOOP_COUNT, HIGH_PRIORITY_CLASS
mov ecx, 1000
.Repeat
test ecx, ecx
cmove eax, ecx
dec ecx
.Until Zero?
counter_end
print str$(eax), 9, "cycles for cmove, test ecx, ecx", 13, 10

counter_begin LOOP_COUNT, HIGH_PRIORITY_CLASS
mov ecx, 1000
.Repeat
test ecx, ecx
jne @F
mov eax, ecx
@@:
dec ecx
.Until Zero?
counter_end
print str$(eax), 9, "cycles for je, test ecx, ecx", 13, 10, 10, 10
ENDM

inkey chr$(13, 10, "--- ok ---", 13)
exit
end start

dedndave

that is a strange result   :red
it's almost as though test ecx,immed is the bad guy - lol
on the last 2 tests, the mov never happens

jj2007

Quote from: dedndave on August 08, 2009, 02:04:32 PM
that is a strange result   :red
it's almost as though test ecx,immed is the bad guy - lol

In a way, yes. Test xxx, 1 is a test for odd or even, and apparently the branch prediction algos are not clever enough to realise that every second iteration is odd. Very odd ::)

Quote
on the last 2 tests, the mov never happens

That was intended. If it happens, timings for branch and cmove are identical.

Ficko

Hi guys!

Sorry I didn't express myself clearly I was almost sleeping. :P

I am using a lots recently this guy "cmov" mainly to determine the Min/Max of two signed or not signed number and thought since MASM has
"IF (SDWORD PTR EAX > EBX)" may somebody did a macro for "CMOV" allready so you not have to strugle with "LE","GE","L" etc..

I did come up with a pseudo macro - dosn't work jet because I have difficulty to pass "<=" as an argument :'( so if anybody could have a guess to fix that would be appreciated or any suggestion
I am not a macro master- :bg

The macro would have as parameters:

CMOV DWORD/SDWORD,Reg1,"Operator",Reg2,OPTIONAL Reg3,OPTIONAL Reg4

It would cmovX Reg1, Reg2 if Reg3 = nothing
otherwise it would cmovX Reg3, Reg4



.686p
.model flat, stdcall
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
CMOV MACRO Sign:REQ,Reg1:REQ,Comp:REQ,Reg2:REQ,Reg3,Reg4
cmp Reg1, Reg2
IF @SizeStr(Reg3)
m1 TEXTEQU <Reg3>
m2 TEXTEQU <Reg4>
ELSE
m1 TEXTEQU <Reg1>
m2 TEXTEQU <Reg2>
ENDIF
IF Sign EQ dword
IF Comp EQ ">"
cmova m1, m2
ELSEIF Comp EQ "<"
cmovb m1, m2
ELSEIF Comp EQ "="
cmove m1, m2
ELSEIF Comp EQ ">=" OR Comp EQ "=>"
cmovae
ELSEIF Comp EQ "<=" OR Comp EQ "=<"
cmovbe
ELSE
echo The Comp operator is not valid  
ENDIF
ELSEIF Sign EQ sdword
IF Comp EQ ">"
cmovge m1, m2
ELSEIF Comp EQ "<"
cmovle m1, m2
ELSEIF Comp EQ "="
cmove m1, m2
ELSEIF Comp EQ ">=" OR Comp EQ "=>"
cmovg
ELSEIF Comp EQ "<=" OR Comp EQ "=<"
cmovl
ELSE
echo The Comp operator is not valid  
ENDIF
ENDIF
ENDM
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
call Pilot
Pilot proc
int 3
CMOV DWORD,eax,"=",ebx,ecx,edx
ret
Pilot endp
end start


dedndave

ahhhh - lol
it's not hard to remember, really
once you have been programming a while, you will have them memorized (unless you use a macro - lol)
(Jcc has pretty much the same mnemonics as CMOVcc and SETcc)

i'd be more inclined to try to write a macro that randomly selects CMOVcc or Jcc/MOV
that way, half the time, you'll have the fastest code

Ficko

If I am tired I not even remember my own name. :lol

And by experience using macros the prg is not that error prone since you use well tested pieces of codes. :U
Quote
i'd be more inclined to try to write a macro that randomly selects CMOVcc or Jcc/MOV

Great idea! :wink

But at first I would be happy to get my first try to work. :bg