lkml.org 
[lkml]   [1998]   [Mar]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [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

\
 
 \ /
  Last update: 2005-03-22 13:41    [W:0.057 / U:1.048 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site