speed and size optimization of p-mode to real mode switch

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Schol-R-LEA

speed and size optimization of p-mode to real mode switch

Post by Schol-R-LEA »

Perica Senjak wrote: I didn't want to Start a New thread, so i will post my Question in this one ;D
Too bad; it really was a different subject. I've moved it now.
Anyways, what i want to do is Clear the ProtectedMode Bit in the cr0 Register, i have this code at the moment -- And i just want to know, would this code work and is there a more Efficient way??;

Code: Select all

mov eax, cr0
shr eax, 1
shl eax, 1
mov cr0, eax
Would the Code above work??
I don't see a reason why it shouldn't work, but whether it would be faster would depend on the processor in question, and possibly the cache and pipeline states. Assuming that the alternative is

Code: Select all

mov eax, cr0
and al, 0xFE   ; the shortest possible way of expressing the operation in terms of size, since you only need to isolate the one byte
mov cr0, eax
then the key factor is whether a single 8-bit immediate AND is slower or faster than two 32-bit register shifts.

I'm short on time right now, but I'll get back to this later.
Perica
Member
Member
Posts: 454
Joined: Sat Nov 25, 2006 12:50 am

Re:speed and size optimization of p-mode to real mode switc

Post by Perica »

..
Last edited by Perica on Sun Dec 03, 2006 8:44 pm, edited 1 time in total.
drizzt

Re:speed and size optimization of p-mode to real mode switc

Post by drizzt »

I agree with School-R-LEA, AFAIK the and operation is the shortest way to clear a bit... but I don't know why... ???
Whatever5k

Re:speed and size optimization of p-mode to real mode switc

Post by Whatever5k »

Actually, both ways require the same time to enable Protected Mode:

shr register, 1 -> needs 2 clocks
shl register, 1 -> needs 2 clocks
TOTAL = 4 clocks

and reg, value -> needs 4 clocks
TOTAL = 4 clocks
Schol-R-LEA

Re:speed and size optimization of p-mode to real mode switc

Post by Schol-R-LEA »

abless wrote: Actually, both ways require the same time to enable Protected Mode:

shr register, 1 -> needs 2 clocks
shl register, 1 -> needs 2 clocks
TOTAL = 4 clocks

and reg, value -> needs 4 clocks
TOTAL = 4 clocks
Thank you Abless, these are the sort of figures I was going to look up, though you don't mention which version of the processor those clock cycles are for.

Also, the instruction [tt]AND AL, imm8[/tt] is a special case, and, at least on older CPUs, is faster than the general [tt]AND reg, imm8[/tt]. Similarly, [tt]SH[[R|L]] reg, 1[/tt], is also faster than the more general [tt]SH[[R|L]] reg, n[/tt] case. In both instances, the special cases are in fact different opcodes from the general cases.

Just to give an example of how these things vary, though, I see that my battered copy of the 80386 Programmer's Manual lists 2 cycles for [tt]AND AL, imm8[/tt], versus 3 cycles apiece for the register shifts. While the difference is negligible, there's no question that what is faster on one processor is not necessarily faster on another.

Also, as Abrash points out, the 'official' cycles are ideal figures, and don't take into account memory cycles, cache misses, pipeline misses, etc. In this case, I would expect that, since both the single immediate mode AND and the sequential SHL/SHR pair take up a total of two bytes total (a one byte opcode and a byte argument inline to the instruction sequence vs. two one byte opcodes), these factor will probably affect both approaches more or less equally, though I personally don't know enough to tell for certain.

In the end, only empirical results - i.e., testing it with a zen timer or a profiler, or both - will actually tell you which is faster, and you'd need to test it on multiple machines and configurations to be sure. Since this is a piece of code that is unlikely to be run very frequently (unless you are running a lot of legacy real-mode programs, changing the video settings very, very often, or using BIOS routines for basic system functions), the effort involved is hardly worth bothering with. Knowing when to optimize is at least as important as knowing how to; if the work spent on optimizing a given piece of code is unlikely to have noticable resutls and would be better spent on other things, then leave it unoptimized.
Whatever5k

Re:speed and size optimization of p-mode to real mode switc

Post by Whatever5k »

Yes, I agree with Schol-R-LEA...
For completeness:

shl/shr instruction:
SHL reg, 1 -> 2 cycles
SHL reg, CL -> 8 + 4*n cycles
SHL mem, 1 -> 15 cycles
SHL mem, CL -> 20 + 4*n cycles

and instruction:
AND reg,reg -> 3 cycles
AND reg,value -> 4 cycles
AND reg,mem -> 9 cycles
AND mem,reg -> 16 cycles

This is known to be correct on a 8086, I don't know how the situation is on newer x86 machines...

Anyway, one clock cycle more or less won't really matter - as Schol-R-LEA already said, these clock cycles are ideal figures...
Schol-R-LEA

Re:speed and size optimization of p-mode to real mode switc

Post by Schol-R-LEA »

Perica Senjak wrote: Hey,

The Bit-Shift way is faster, i'll tell you why in a moment. First of all, the Bit-Shift code should be done like this;

Code: Select all

mov eax, cr0
shr al, 1
shl al, 1
mov cr0, eax
The above code isn't much different to the one before, i just thought using the Lower Part of the (e)ax register would be more appropriate ;D (And Possibly Faster); As it is not necessary to do the Shift on the Whole Register, Because the ProtectedMode Bit is at the Very Beginning!
With a single-bit register shift, the register information is encoded in the Mod R/M byte that follows the opcode, and is one byte in size regardless of the registers in question. Since the shift operation is done in parallel, across the whole register at once, there should be no speed difference between operating on a byte register and operating on a doubleword register.
Why do i think the Bit-Shift way is faster? Well, the "and" Bit Operation has to Compare Each Bit, then it has to make the appropriate changes to it (If any have to be made); Yes the Bit-Shift uses two instructions, But it's faster -- Because all the CPU has to do is move the Bits (Which is a very fast instruction, it isn't much work for the CPU to do Bit-Shifts), but when you use the "and" Operation: It has to compare Each Bit, one by one (Which would take longer);

Well, this is my Theory of which one is faster -- I don't know for a fact, i just figure ;D

What do you think??
I think you should read up on digital logic, CPU architecture and the details of Intel processor optimization. The hardware operations on the registers are parallel, not serial; it does the comparison on all bits at once, not one at a time. If I had time, I make a diagram, but that can wait. Furthermore, AND in particular is one of the fastest operations the ALU can perform. It ought to be; the majority of the circuits in the processor are built out of NAND and NOR logic subunits, AFIAK.

In any case, isn't it a bit early in your design to worrying about optimization? It is generally accepted wisdom that optimizing code is one of the last steps of design, to be done after a complete, stable working version is already completed. There are good reasons or this, starting with the fact that optimized code is often much harder to modify and debug. Also, it is important to know when and where to optimize; spending a lot of time tweaking a code section that runs only infrequently (like this one), and makes no perceptible change in performance (ditto - the difference in speed is drowned out by the time it takes to read and reload the CR0), is a wasted effort.
Schol-R-LEA

Re:speed and size optimization of p-mode to real mode switc

Post by Schol-R-LEA »

I did notice that I was wrong about the size of the shift operations; as I told Perica, they are two bytes per instruction (opcode and mod byte), not one byte as I originally said. This would imply that the shift approach is likely to be slightly slower, if anything, though as I said the total effect of optimizing this piece of code is minimal at best.
.bdjames

Re:speed and size optimization of p-mode to real mode switc

Post by .bdjames »

Hello,

dec eax
Schol-R-LEA

Re:speed and size optimization of p-mode to real mode switc

Post by Schol-R-LEA »

.bdjames wrote: Hello,

dec eax
This is not a good idea; if by some error it is used when the bit in question is already clear, it will alter the rest of the register undesirably. Besides, it isn't necessarily any faster than AND AL, 0xFE is in this case.
Perica
Member
Member
Posts: 454
Joined: Sat Nov 25, 2006 12:50 am

Re:speed and size optimization of p-mode to real mode switc

Post by Perica »

..
Last edited by Perica on Sun Dec 03, 2006 8:45 pm, edited 1 time in total.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:speed and size optimization of p-mode to real mode switc

Post by Pype.Clicker »

Just to avoid the fact need for books crawling for some digital logic infos (which you should read one, because it will enlight you as a bless of the OS gods ;) ), you should know what computers can easily do in a single cycle:

- shifting bits by a fixed amount : this is just done by wiring bit 1 to bit 0, bit 2 to bit 1, bit 3 to bit 2, ... The [eax*4] address construction uses that technique as well as shl/shr/sar ... do. shifting by a variable amount may require a more complicated operation, but it usually won't require 9 cycles to perform shr eax,cl when cl == 9.

- selecting a value among 2 possible ones. This is done by a circuit called a multiplexor: if you have x[0..31] and y[0..31] (bit vectors), you can have "z = if b then x else y" with "z <-- x.b + y.!b"

- ANDing, ORing, XORing, NOTing bits. This is one of the fastest possible operation because the same processing is applied to every bit without any inter-bits dependencies (unlike the ADD/SUB operation which have carries and borrows from one row of bits to another). However, do not start imagining that ADD eax,1 will be slower than AND eax,1: Intel has slowed down its CPU so that it can do one ADD per cycle, which means even if the result of an AND is ready earlier than the output of an ADD, the result will not be used before and ADD would have completed. Hope i made myself clear.

- ADDing, SUBing are one-cycle too. MULs and DIVs are always longer. The algorithms used are often close to what you do with hand-written operations for MULs and DIVs, but easier because you're working in binary:

mul(int x, int y) {
for( int r=0; x; x=x>>1, y=y<<1)
if (x&1) r+=y;
}

- MOVing between registers and L1-cache is usually made one-cycle too.
Post Reply