• Welcome to Valhalla Legends Archive.
 

Fastest way to do common things

Started by Telos, February 29, 2004, 09:47 AM

Previous topic - Next topic

Telos

I was writing a program that had two opreations that needed to be repeated quite a few times so I was trying to figure out the best way to optimize these two tasks

The first is toggling a boolean and we came up with

x = ( x ? false : true );

cmp dword ptr [x],0
sete al  
movzx ecx,al
mov dword ptr [x],ecx



x = !x;

xor eax, eax
cmp dword ptr [x], 0
sete al
mov dword ptr [x], eax



x ^= 1;

mov eax, dword ptr [x]
xor eax, 1
mov dword ptr [x], eax


With the boolean data type these three worked fine x ^= 1 being the fastest however when you use an integer the following seemed to be the fastest (should be only 3 clock cycles?)


__asm { not x }

not dword ptr [x]


or even if x is a bool


__asm { not dword ptr[x] }


or

__asm { xor dword ptr [x], 1 }

but thats more dependent on what x is

Secondly an equality comparison for three integers
Zakath suggested

if( x == y && y == z )


I ended up using

if( x == ( y & z ) )


But I didnt do any disassembly on these to figure out which way is the fastest or even if there are better ways to do it

If anyone has a faster/better/cooler way of doing these please post them

Adron

Quote from: Telos on February 29, 2004, 09:47 AM
The first is toggling a boolean and we came up with

x = ( x ? false : true );

cmp dword ptr [x],0
sete al  
movzx ecx,al
mov dword ptr [x],ecx



x = !x;

xor eax, eax
cmp dword ptr [x], 0
sete al
mov dword ptr [x], eax


Is x an int or a bool? Your code is useful for turning an integer value into a real bool. We posted about this earlier on the asm board. My favorite for setting eax = !eax was "neg eax; sbb eax,eax; inc eax".


Quote from: Telos on February 29, 2004, 09:47 AM

x ^= 1;

mov eax, dword ptr [x]
xor eax, 1
mov dword ptr [x], eax


"xor dword ptr

Telos

Quote from: Adron on February 29, 2004, 10:25 AM
Is x an int or a bool? Your code is useful for turning an integer value into a real bool. We posted about this earlier on the asm board. My favorite for setting eax = !eax was "neg eax; sbb eax,eax; inc eax".

I tried using x as both for these tests in the program it hasnt made much difference which data type to use

Quote from: Adron on February 29, 2004, 10:25 AM
"xor dword ptr
  • , 1" should be faster than moving it into a register if you're not going to use the register for anything else. Toggling bit 0 works only if you know that x is a bool value from the start.
Yes which is why Im wary to use that unless Ive set the value initially and its not an int

Quote from: Adron on February 29, 2004, 10:25 AM
That's "x = ~x", not "x = !x".

Ok but I dont think I said that asm not was equivalent to the ! operator

Quote from: Adron on February 29, 2004, 10:25 AM
This is incorrect if x is a bool - a bool should be 0 or 1. Try "neg x; inc x" or "xor x, 1".

Incorrect how?  Stepping through with a debugger shows correct values at that location at each step

Quote from: Adron on February 29, 2004, 10:25 AM
That's dependent on x being a bool, and works.

Yes which is why I said depends on the type of x

Quote from: Adron on February 29, 2004, 10:25 AM
Your answer is incorrect. It will return true for x = 2, y = 6, z = 10.

I should have clarified this one x y and z can only be 0 1 or 2 in this program so while it doesnt work on the general case it does in this program thx for input tho

Adron

Quote from: Telos on February 29, 2004, 10:34 AM
Quote from: Adron on February 29, 2004, 10:25 AM
Is x an int or a bool? Your code is useful for turning an integer value into a real bool. We posted about this earlier on the asm board. My favorite for setting eax = !eax was "neg eax; sbb eax,eax; inc eax".

I tried using x as both for these tests in the program it hasnt made much difference which data type to use

It makes a lot of difference. A C++ bool value can be expected to be either 0 or 1, while a C boolean integer value can be expected to be either 0 or nonzero. This makes testing a C boolean require more code/time than testing a C++ bool.



Quote from: Telos on February 29, 2004, 10:34 AM
Ok but I dont think I said that asm not was equivalent to the ! operator

Ah, I may have misinterpreted you. I thought those were all intended to be examples of "toggling a boolean value", either as a C++-style bool variable, or as a C-style zero or nonzero integer. If you use that code to toggle a C-style boolean value stored in an integer, most true values input will generate a true value as output...



Quote from: Telos on February 29, 2004, 10:34 AM
Incorrect how?  Stepping through with a debugger shows correct values at that location at each step


__asm { not dword ptr[x] }

is incorrect if x is a bool because:

if x is 0 before the statement, x will not be 1 after the statement (x will be -1).

if x is 1 before the statement, x will not be 0 after the statement (x will be -2).


Quote from: Telos on February 29, 2004, 10:34 AM
I should have clarified this one x y and z can only be 0 1 or 2 in this program so while it doesnt work on the general case it does in this program thx for input tho

If all those values are acceptable, it's once again incorrect because it will return true for x = 0, y = 1, z = 2. You need to specify more exactly the conditions under which your statements are supposed to work.

Telos

Quote from: Adron on February 29, 2004, 12:14 PM
It makes a lot of difference. A C++ bool value can be expected to be either 0 or 1, while a C boolean integer value can be expected to be either 0 or nonzero. This makes testing a C boolean require more code/time than testing a C++ bool.

(Hasnt made much different with respect to how it is toggled)

Quote from: Adron on February 29, 2004, 12:14 PM
Ah, I may have misinterpreted you. I thought those were all intended to be examples of "toggling a boolean value", either as a C++-style bool variable, or as a C-style zero or nonzero integer. If you use that code to toggle a C-style boolean value stored in an integer, most true values input will generate a true value as output...

Probably not the fact that I was testing two data types has been confusing in this thread

Quote from: Adron on February 29, 2004, 12:14 PM

__asm { not dword ptr[x] }

is incorrect if x is a bool because:

if x is 0 before the statement, x will not be 1 after the statement (x will be -1).

if x is 1 before the statement, x will not be 0 after the statement (x will be -2).

I see what youre saying but the initial value (its bool x in this case) is 0 and not dword ptr
  • makes it true and not dword ptr
  • makes it false and so on

    Quote from: Adron on February 29, 2004, 12:14 PM
    If all those values are acceptable, it's once again incorrect because it will return true for x = 0, y = 1, z = 2. You need to specify more exactly the conditions under which your statements are supposed to work.

    Its just a simple tic tac toe frontend for an AI and with the cases I use x == (y & z) has been fine but theres the possibility that I havent run into a case that will cause a false positive thx for input will fix

Adron

#5
Quote from: Telos on February 29, 2004, 04:51 PM
Quote from: Adron on February 29, 2004, 12:14 PM
It makes a lot of difference. A C++ bool value can be expected to be either 0 or 1, while a C boolean integer value can be expected to be either 0 or nonzero. This makes testing a C boolean require more code/time than testing a C++ bool.

(Hasnt made much different with respect to how it is toggled)

The difference of knowing that a value is either 0 or 1, or knowing that it is either zero or nonzero makes a huge difference on how to toggle it. Toggling a bool means toggling a bit, toggling a C boolean means detecting a nonzero value. It *is* very different.



Quote from: Telos on February 29, 2004, 04:51 PM
Probably not the fact that I was testing two data types has been confusing in this thread

I think so. Also, for bool, you shouldn't be accessing it as a dword ptr at all, because most bools are just 8 bits.


Quote from: Telos on February 29, 2004, 04:51 PM
I see what youre saying but the initial value (its bool x in this case) is 0 and not dword ptr
  • makes it true and not dword ptr
  • makes it false and so on
"not dword ptr [ x ]" when x is 0 doesn't give it the bool value "true", so it's incorrect.



Quote from: Telos on February 29, 2004, 04:51 PM
Its just a simple tic tac toe frontend for an AI and with the cases I use x == (y & z) has been fine but theres the possibility that I havent run into a case that will cause a false positive thx for input will fix

Well, if you'd define the possible combinations, it'd be easier to give you an answer to whether it works or not.... :P

Telos

Quote from: Adron on February 29, 2004, 06:52 PM
["not dword ptr [ x ]" when x is 0 doesn't give it the bool value "true", so it's incorrect.

I dont know where you get this from but it does toggle the value correctly Im having a hard time understanding why its incorrect

Kp

Quote from: Telos on February 29, 2004, 08:40 PM
Quote from: Adron on February 29, 2004, 06:52 PM["not dword ptr [ x ]" when x is 0 doesn't give it the bool value "true", so it's incorrect.
I dont know where you get this from but it does toggle the value correctly Im having a hard time understanding why its incorrect

As he stated earlier, not 0 is ~0 which is all bits on, which is not equivalent to 0x01.  The bool value 'true' is typically the byte value 0x01, not "any value which is not 0x00."  Thus, your method produces a value that, while not zero, is not the correct value of true for a bool.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

Telos

Is 0x01 true?  Yes

Is 0 true?  No
Is ~0 true?  Yes
Is ~(~0) true?  No
Is ~(~(~0)) true?  Yes

Boolean is either true or false right?  So does it really matter what value of true or false is used?  Clearly the CPU doesnt think so

Grok

"By definition, true has the value 1 when converted to an integer and false has the value 0.  Conversely, integers can be implicitly converted to bool values: nonzero integers convert to true and 0 converts to false."

So you're really discussing whether an implicit conversion is involved vs. the defined true.

Arta

#10
It could, if your compiler assumes that true is always 1 and false is always 0... I doubt that any compiler would work like this, but the following example comes to mind:


bool eax = true;
if(eax) return false; // I know it's ugly, but bear with me


Might be compiled to something like:


test al, al
jz somewhere_else
dec al
ret


If your toggle had changed al from 1 to some other nonzero value, that would return an unexpected result. Like I said, I don't think it's really a viable situation, but it sprang to mind.

Edit: bah, it's late.

Adron

A bool is supposed to be either 0 or 1, which allows certain optimizations. Giving a bool the value 2 or -1 is not acceptable. This most likely produces a warning in  msvc++ about forcing a conversion:

bool func(int a, int b)
{
  a &= b;
  return a;
}

The reason is that the compiler has to emit code to turn any nonzero value of a into 1, or the return value will not be a bool.

l)ragon

#12
correct me if i'm wrong but shouldent the statement x = ( x ? false : true );
be set up like x = ( x ? trueparthere : falseparthere );

Quote from: K on March 01, 2004, 04:04 PM
Quote from: dRAgoN on March 01, 2004, 04:01 PM
correct me if i'm wrong but shouldent the statement x = ( x ? false : true );
be set up like x = ( x ? trueparthere : falseparthere );

No, he's trying to toggle the value; so if x is true, x becomes false and vice versa.
thx was just wondering
*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*ˆ¨¯¯¨ˆ*^~·.,l)ragon,.-·~^*ˆ¨¯¯¨ˆ*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*

K

Quote from: dRAgoN on March 01, 2004, 04:01 PM
correct me if i'm wrong but shouldent the statement x = ( x ? false : true );
be set up like x = ( x ? trueparthere : falseparthere );

No, he's trying to toggle the value; so if x is true, x becomes false and vice versa.