Compilatore CL (VC) su x86
int pari1 (int x) { return !(x % 2); }
codice:
mov eax, DWORD PTR _x$[esp-4] ; il parametro x
and eax, -2147483647 ; 80000001H
jns SHORT $L559
dec eax
or eax, -2 ; fffffffeH
inc eax
$L559:
neg eax
sbb eax, eax
inc eax
ret 0
int pari2 (int x) { return !(x & 1); }
codice:
mov eax, DWORD PTR _x$[esp-4] ; il parametro x
not eax
and eax, 1
ret 0
Compilatore gcc su x86
int pari1 (int x) { return !(x % 2); }
codice:
pushl %ebp
movl %esp,%ebp
movb 8(%ebp),%al
notl %eax
andl $1,%eax
leave
ret
int pari2 (int x) { return !(x & 1); }
codice:
pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%eax
xorb $1,%al
andl $1,%eax
leave
ret
codice di test
codice:
#include <stdio.h>
#include <time.h>
#define LOOPS 1000000
int pari1 (int x) { return !(x % 2); }
int pari2 (int x) { return !(x & 1); }
clock_t bench(int (*f)(int), int* tot)
{
int i;
clock_t t0,t1;
t0 = clock();
for (i = 0; i < LOOPS; i++)
*tot += f(i);
t1 = clock();
return t1 - t0;
}
int main()
{
int i, tot1 = 0, tot2 = 0;
double e[2] = {0.0};
for (i = 0; i < 1000; i++)
{
e[0] += (double)(bench(pari1, &tot1)) / CLOCKS_PER_SEC;
e[1] += (double)(bench(pari2, &tot2)) / CLOCKS_PER_SEC;
}
for (i = 0; i < 1000; i++)
{
e[1] += (double)(bench(pari2, &tot2)) / CLOCKS_PER_SEC;
e[0] += (double)(bench(pari1, &tot1)) / CLOCKS_PER_SEC;
}
printf("%% %.3fs %d\n", e[0], tot1);
printf("& %.3fs %d\n", e[1], tot2);
return 0;
}
il codice è stato scritto in modo da forzare il compilatore ad eseguire il loop, altrimenti quando viene attivata l'opzione di ottimizzazione non li eseguirà affatto, il caching può dare fastidio
ecco il perchè dei due loop incrociati.
Test su
CPU: AMD XP 1600+ (1400 Mhz)
RAM: 1 Gbyte DDR 2100 (2 moduli da 512 MB)
OS: win
cl (visual c) modalita Relase
% 5.758s 1000000000
& 5.718s 1000000000
gcc 3.3.2 opzione -O3
% 16.758s 1000000000
& 17.857s 1000000000
devo provarlo su linux.