Compilatore CL (VC) su x86
int pari1 (int x) { return !(x % 2); }
int pari2 (int x) { return !(x & 1); }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
Compilatore gcc su x86codice:mov eax, DWORD PTR _x$[esp-4] ; il parametro x not eax and eax, 1 ret 0
int pari1 (int x) { return !(x % 2); }
int pari2 (int x) { return !(x & 1); }codice:pushl %ebp movl %esp,%ebp movb 8(%ebp),%al notl %eax andl $1,%eax leave ret
codice di testcodice:pushl %ebp movl %esp,%ebp movl 8(%ebp),%eax xorb $1,%al andl $1,%eax leave ret
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 fastidiocodice:#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; }
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.

Rispondi quotando