News:

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

Discussion on instructions

Started by jj2007, August 10, 2008, 02:01:21 PM

Previous topic - Next topic

jj2007

> cmp SomeString[0], 0

Paul, I had not yet tested this one thanks. Apparently it's difficult to do this simple test with less than 7 bytes...

   int 3   ; tell Olly you want to see this
   cmp MyText[0], 0   ; 7 bytes

   mov al, MyText[0]   ; 5+2=7 bytes
   test al, al

   mov al, byte ptr MyText   ; 5+2=7 (same code as before)
   test al, al

   test byte ptr MyText, 0   ; 7 bytes

   mov eax, offset MyText   ; 9 bytes
   mov al, [eax]
   test al, al

PBrennick

JJ,
For me, it is not a question about the amount of bytes consumed, it is no longer that important. I like the simplicity of the instruction.

And God knows I do not want to beat a dead horse but you DO seem to have a penchant to do two things:

1. Use destructive instructions that can be done nondestructively (CMP opposed to MOV).
2. Utilize precious registers to do a job that can be done without tying them up.

Now, those two things are important to ME.

Just an observation,
-- Paul
The GeneSys Project is available from:
The Repository or My crappy website

jj2007

Quote from: PBrennick on August 10, 2008, 10:26:43 PM
1. Use destructive instructions that can be done nondestructively (CMP opposed to MOV).
2. Utilize precious registers to do a job that can be done without tying them up.

Paul, I was just playing around trying to find an even more elegant solution - but yours is clearly the best, it seems. As to destructive solutions, my definition of destructive is "changes the content of a precious register". That is not the case for
   mov eax, 12345678h   ; test value
   cmp eax, 0   ; 3 bytes   
   test eax, eax   ; 2 bytes
   or eax, eax   ; 2 bytes
   and eax, eax   ; 2 bytes
... and even this pair of instructions is not destructive according to that definition:
   inc eax   ; 2*1 = bytes
   dec eax
So you see I am indeed concerned about not wasting registers  :thumbu
As to size, yes I tend to be a bit ideological, as a manifestation against the 15,000,000,000 bytes of hot air that Vista wants to stuff down our throats. On the other hand, even under speed aspects size matters: If you have a medium sized project, you may reach the limits of the L1 cache, and then it pays off if your libraries take care of speed and size.

PBrennick

Almost every example you posted is destructive, Anytime the value of a register has been change it has been destroyed as it 'has' changed. Important info is lost.

   mov eax, 12345678h   ; eax has been changed
   cmp eax, 0   
   test eax, eax
   or eax, eax   ; Technically has changed but doesn't matter, still a bad habit
   and eax, eax   ;same as above, but worse
   inc eax   ; eax has been changed
   dec eax  ; eax has been changed

Changed means destroyed as the original value has been lost.
-- Paul
The GeneSys Project is available from:
The Repository or My crappy website

jj2007

Quote from: PBrennick on August 11, 2008, 11:58:04 AM
   mov eax, 12345678h   ; eax has been changed

Please quote me correctly:
mov eax, 12345678h   ; test value

I dubbed this "test value" so that the reader of this post can easily check whether eax has been "destroyed" or not by the code that follows the wrongly quoted line, e.g. with a simple

MsgBox 0, hex$(eax), addr AppName, MB_OK

zooba

Quote from: PBrennick on August 11, 2008, 11:58:04 AM
Changed means destroyed as the original value has been lost.

It also (probably) means that accesses to that register cannot be reordered around that instruction. With register renaming, the actual register changes even though the name and contents remain the same.

It would be possible for the CPU design to optimise this out, as xor reg32,reg32 is (apparently) optimised, though I see no reason why the CPU design should specially handle what Paul so aptly describes as a bad habit.

(Also, cache concerns only really apply for a tight loop. If you plan on fitting an entire application in there you'd better inform the user that they can't have any other programs running at the same time, since they will also want to use the cache.)

Cheers,

Zooba :U

hutch--

The comon notion of "destructive" is one of where a register is WRITTEN TO.


mov eax, eax


The register remains the same but it has had itself written back to itself.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

jj2007

Quote from: jj2007 on August 10, 2008, 02:01:21 PM
> cmp SomeString[0], 0

Paul, I had not yet tested this one thanks. Apparently it's difficult to do this simple test with less than 7 bytes...

That's how I entered into the thread - with a thank you.

Quote from: PBrennick on August 10, 2008, 10:26:43 PM
...you DO seem to have a penchant to do two things:

1. Use destructive instructions that can be done nondestructively (CMP opposed to MOV).
2. Utilize precious registers to do a job that can be done without tying them up.

That's the answer I got - a personal attack saying I am an evil man who destroys and wastes registers.

Quote from: zooba on August 11, 2008, 12:54:32 PM
With register renaming, the actual register changes

Correct - and it might have an impact on a relevant aspect of programming, i.e. speed.

I appreciate your intent to contribute with logical arguments. I think it would help if we separated two models of the CPU:

1. The logical model
2. The physical model

In the logical model, or eax, eax and and eax, eax do not change the content of the register; so there is no harm in using these instructions because they will not break your code (and indeed, Masm and JWasm use them for high level constructs, although nobody would have stopped them from using test eax, eax instead)

Now, in the physical model, we have two sub-versions:
a) the folkloristic one: "These instructions are destructive, so the code must be slower because the poor CPU is working harder"
b) the one underpinned by measurable facts:

Quote from: MichaelW on August 07, 2008, 08:18:15 PM
On my P3, in a contrived test that does not use the result, OR is faster [than test eax, eax], but in a more realistic test that does use the result there is no measurable difference.

Speed is measurable. So is CPU temperature - maybe the CPU heats up some millidegrees after some zillion loops with "evil" or eax, eax instead of "benign" test eax, eax instructions; but I don't have the means to test that. Grateful if the hardware freaks could provide a link to Intel's lab research on this topic... :wink

To conclude, I am always open to a nice exchange of arguments based on figures.

hutch--

 :bg

> That's the answer I got - a personal attack saying I am an evil man who destroys and wastes registers.

I am an evil person who does NOT waste registers.  :P
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Mark Jones

Oh no, is this the part where we argue over wether CP/M or VAX "destroy" more registers? :wink
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

jj2007

Quote from: Mark Jones on August 11, 2008, 08:40:13 PM
Oh no, is this the part where we argue over wether CP/M or VAX "destroy" more registers? :wink
Me grown up with Fortran IV on a PDP-11, never had any problems with destroyed registers... :bg

PBrennick

JJ,
Perhaps you did not notice my comment about Michael's test which was performed with no cache loading. It makes it invalid because even if it is NOT a regular scenario, the cache can load and a that point the instruction will slow down. You do not seem to want to listen to good advice and always claim that when these things are pointed out to you that we are attacking you. No one is attacking you and you are definitely free do anything what you wish; but when you misrepresent information on this board that people who are learning will read and reach wrong conclusions and develop bad habits - you can expect several of us to take notice and will speak up.

Mark Larson recently spoke up about an error in advice that I had made. I did not cry about it, I did not try to fight an unwinnable war; I moved on.

This is what makes this board work. On a bad day when someone makes an unfortunate mistake, there is someone to come to the rescue. We all work together this way and no one takes it personally. You, on the other hand, are a discordant note, I do not know how this will all resolve but I fear the worse. In the other topic, we all moved on to other things to take the heat off you as everyone likes you. You do not seem to have noticed that and are just hijacking other threads to continue preaching. Please stop, it is sad.

-- Paul
The GeneSys Project is available from:
The Repository or My crappy website

jj2007

Quote from: PBrennick on August 11, 2008, 10:25:24 PM
JJ,
Perhaps you did not notice my comment about Michael's test which was performed with no cache loading. It makes it invalid because even if it is NOT a regular scenario, the cache can load and a that point the instruction will slow down.

That's interesting. You mean this post, right?

Quote from: PBrennick on August 08, 2008, 12:33:13 AM
Michael,
None of those tests involve a memory to registe,r or register to memory operation which is where the bottleneck is as I already said.

Also, Michael, something for you to think about in terms of your macros is the fact that they do not perform any cache loading so a test between instructions where one writes to the cache and another doesn't is not really valid.

And finally, back to the original point of all this OR 'is' destructive.

-- Paul


Red highlighting by myself. Could you please explain which cache is involved in the or eax, eax vs test eax, eax case? As you see, I do listen, and I am eager to learn from older colleagues.

NightWare

Quote from: jj2007 on August 11, 2008, 11:01:15 PM
Could you please explain which cache is involved in the or eax, eax vs test eax, eax case? As you see, I do listen, and I am eager to learn from older colleagues.
jj, rewrite the register is really a bad habit, coz you have a stall (wait for result written in the register), and it's not the case for 'non destructive' instructions...  :wink

PBrennick

Read the documentation, it is clear you have not - to this point. Especially if you do not know what a 'write cache' is. That is what the stall is all about, the pending write will happen and the stall ends. If the CPU is not to busy, the stall is minor or non-existant. This is what leads to results in timing macros that are suspect.

Since Michael's timing macros are mostly used by the 'optimization crowd' who know all this all too well and do not have these habits, the results of his macros are very dependable. But, like anything else, if you misuse a tool ...

You are arguing at this point, and angry, this is what leads you to write things like, " I do listen, and I am eager to learn from older colleagues." especially when you have no intention of listening at all. Since you are arguing and you will NOT listen, thiis has become a waste of time better spent.

-- Paul
The GeneSys Project is available from:
The Repository or My crappy website