This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Asm code runs slower with -O
- From: Mihnea Balta <dark_lkml at mymail dot ro>
- To: gcc-help at gcc dot gnu dot org
- Date: Mon, 20 Jan 2003 19:45:22 +0200
- Subject: Asm code runs slower with -O
Hello,
I'm attaching a source file which contains two checksum routines, one
written in asm and the other in plain C.
If I compile with -O or -O2, the program runs about 1.3-1.5 times SLOWER
than with no optimizations. My compiler is gcc-2.95.3 and my test machine is
an AMD Athlon @ 1145 Mhz.
Please bear with me if there's something wrong with my asm routine, since
I'm just beginning to learn how gcc inline asm works.
/*
* Benchmark for udp checksum code, C version or asm version
*/
#include <sys/timeb.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
//typedef unsigned int uint;
typedef unsigned short word;
typedef unsigned long long uint64;
uint64 get_time(){
struct timeb tm;
uint64 ret;
ftime(&tm);
ret = tm.time;
ret *= 1000;
ret += tm.millitm;
return ret;
}
int main(){
char buf[1024];
char pseudo[12];
uint* p;
int i, cnt;
uint a, b, sum, len, os, proto_and_len;
uint64 st, ed;
/*
* We use a random len because we don't want gcc to use it as a constant,
* since we want to simulate real-life conditions
*/
srand(time(0));
len = 1000 + (uint) (24.0*rand()/(RAND_MAX+1.0));
if(len % 4)
len += 4 - (len%4);
printf("len: %d\n", len);
a = 0xababf1f1;
b = 0xcccccccc;
for(i=0; i<1024; i++)
buf[i]=(char) (256.0*rand()/(RAND_MAX+1.0));
*(uint*)pseudo = a;
*(uint*)(pseudo+4) = b;
*(uint*)(pseudo+8) = (len<<16)+17*256;
/* ASM VERSION */
st = get_time();
proto_and_len = (len<<16)+17*256;
for(cnt=0; cnt<100000; cnt++){
__asm__ __volatile__ ("
/* sum the pseudo-header values */
movl %1, %0
addl %2, %0
adcl %3, %0
adcl $0, %0
/* fold and complement */
movl %0, %%ebx
shrl $16, %0
addw %%bx, %w0
adcl $0, %0
notl %0
andl $0x0000ffff, %0
/* add packet */
shrl $2, %%ecx
clc
1: adcl (%5), %0
lea 4(%5), %5
decl %%ecx
jne 1b
adcl $0, %0
/* fold and complement */
movl %0, %%ebx
shrl $16, %0
addw %%bx, %w0
adcl $0, %0
notl %0
andl $0x0000ffff, %0
"
/* the damn compiler uses esi for sum if we say "=r" here !! */
: "=a"(sum)
: "g"(a), "g"(b), "g"(proto_and_len), "c"(len), "S"(buf)
: "%ebx"
);
}
ed = get_time();
printf("sum: %x; elapsed time: %d\n", sum, ed-st);
/* PLAIN C VERSION */
st = get_time();
for(cnt=0; cnt<100000; cnt++){
sum = 0;
p = (typeof(p))pseudo;
i = 12;
while( i > 1 ) {
os = sum;
sum += *p;
if(sum < os)
++sum;
++p;
i -= sizeof(*p);
}
/* Fold 32-bit sum to 16 bits */
while (sum>>16)
sum = (sum & 0xffff) + (sum >> 16);
sum = (~sum) & 0x0000ffff;
p = (typeof(p))buf;
i = 1024;
while( i > 1 ) {
os = sum;
sum += *p;
if(sum < os)
++sum;
++p;
i -= sizeof(*p);
}
/* Fold 32-bit sum to 16 bits */
while (sum>>16)
sum = (sum & 0xffff) + (sum >> 16);
sum = (~sum) & 0x0000ffff;
}
ed = get_time();
printf("sum: %x; elapsed time: %d\n", sum, ed-st);
return 0;
}