Messages in this thread | | | Date | Wed, 25 Mar 1998 23:16:08 +0100 (CET) | From | MOLNAR Ingo <> | Subject | Re: [PATCH] APM support doesn't compile with binutils 2.8.1.0.24 |
| |
On Wed, 25 Mar 1998, Linus Torvalds wrote:
> > That is wrong since performance should be same for 16-bit and > > 32-bit forms. The only difference is "mov/movl %ds,%eax" will > > trach the high 16 bits of %eax. > > Wrong. The version with a operand size prefix is SLOWER when you are > running on a Pentium. Look into the Pentium manuals: the operand size > prefix takes one cycle, and also makes the instruction unpairable.
moving segment registers is unpairable already, but the change in entry.S (where two movw's were changed to movl's) nevertheless showed a 1 cycle improvement in null-syscall latency. It could be the ALIGN thing right after the call *() into the syscall table. But i've attached some code that demonstrates that 'movw %ds' is inherently slower than 'movw %ds', on pentiums:
code block A:
ASM (" movw %ds, %ax; movw %es, %bx"); ASM (" movw %ds, %ax; movw %es, %bx"); ASM (" movw %ds, %ax; movw %es, %bx"); ASM (" movw %ds, %ax; movw %es, %bx"); ASM (" movw %ds, %ax; movw %es, %bx");
executes in 19 cycles. block B:
ASM (" nop; movl %ds, %ax; nop; nop; movl %es, %bx"); ASM ("nop; nop; movl %ds, %ax; nop; nop; movl %es, %bx"); ASM ("nop; nop; movl %ds, %ax; nop; nop; movl %es, %bx"); ASM ("nop; nop; movl %ds, %ax; nop; nop; movl %es, %bx"); ASM ("nop; nop; movl %ds, %ax; nop; nop; movl %es, %bx");
executes in _20_ cycles only, although it has 19 more nop's in it, and has +25% more code length than block A...
so, in case the test program is correct, there seems to be some nontrivial cost wrt. 'movw %ds,<reg>' on pentiums, but it's not a pairing issue. [and it's neither some sort of register collision issue, access to es,ds,ax,bx is interleaved properly.]
the testcode has to be run as root, it should produce something like this:
[root@hell asm]# ./test2 best pushw latency: 19 cycles best pushl latency: 20 cycles
it's not impossible that the code is bogus, although i triple checked it. It was run on a true pentium.
-- mingo
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <sys/wait.h> #include <linux/unistd.h>
static unsigned int t1,t2;
#define ASM __asm__ __volatile__ #define CYCLES(x) ASM ("rdtsc" :"=a" (x)::"edx")
void main() { unsigned int i, min1=-1, min2=-1;
iopl(3); ASM("cli"); for (i=0; i<100000; i++) {
ASM(".align 32"); CYCLES(t1); ASM (" movw %ds, %ax; movw %es, %bx"); ASM (" movw %ds, %ax; movw %es, %bx"); ASM (" movw %ds, %ax; movw %es, %bx"); ASM (" movw %ds, %ax; movw %es, %bx"); ASM (" movw %ds, %ax; movw %es, %bx"); CYCLES(t2); if (t2-t1 < min1) min1 = t2-t1;
ASM(".align 32"); CYCLES(t1); ASM (" nop; movl %ds, %ax; nop; nop; movl %es, %bx"); ASM ("nop; nop; movl %ds, %ax; nop; nop; movl %es, %bx"); ASM ("nop; nop; movl %ds, %ax; nop; nop; movl %es, %bx"); ASM ("nop; nop; movl %ds, %ax; nop; nop; movl %es, %bx"); ASM ("nop; nop; movl %ds, %ax; nop; nop; movl %es, %bx"); CYCLES(t2); if (t2-t1 < min2) min2 = t2-t1; }
printf("best pushw latency: %u cycles\n", min1-13); printf("best pushl latency: %u cycles\n", min2-13); }
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu
| |