2010-04-29 6 views
10

Comment puis-je démontrer aux étudiants la facilité d'utilisation de likely et de unlikely indices de compilateur (__builtin_expect)? Pouvez-vous écrire un exemple de code, qui sera plusieurs fois plus rapide avec ces conseils comparant le code sans indices.exemple d'apprentissage des indices de compilateur probables() et peu probables (

+2

http://kerneltrap.org/node/4705 –

+0

@ T.J. Crowder, oui. mais je veux un exemple de programme dans lequel les étudiants peuvent sentir la différence, ne pas le lire en assembleur. – osgx

+1

@osgx: Vous n'obtiendrez pas un tel échantillon, car il n'y a pas de différence à ressentir. C'est le pire, le plus laid type de micro-optimisation inutile. –

Répondre

22

Voici celui que j'utilise, une mise en œuvre très inefficace des nombres de Fibonacci:

#include <stdio.h> 
#include <inttypes.h> 
#include <time.h> 
#include <assert.h> 

#define likely(x) __builtin_expect((x),1) 
#define unlikely(x) __builtin_expect((x),0) 

uint64_t fib(uint64_t n) 
{ 
    if (opt(n == 0 || n == 1)) { 
     return n; 
    } else { 
     return fib(n - 2) + fib(n - 1); 
    } 
} 

int main(int argc, char **argv) 
{ 
    int i, max = 45; 
    clock_t tm; 

    if (argc == 2) { 
     max = atoi(argv[1]); 
     assert(max > 0); 
    } else { 
     assert(argc == 1); 
    } 

    tm = -clock(); 
    for (i = 0; i <= max; ++i) 
     printf("fib(%d) = %" PRIu64 "\n", i, fib(i)); 
    tm += clock(); 

    printf("Time elapsed: %.3fs\n", (double)tm/CLOCKS_PER_SEC); 
    return 0; 
} 

Pour démontrer, en utilisant GCC:

~% gcc -O2 -Dopt= -o test-nrm test.c 
~% ./test-nrm 
... 
fib(45) = 1134903170 
Time elapsed: 34.290s 

~% gcc -O2 -Dopt=unlikely -o test-opt test.c 
~% ./test-opt 
... 
fib(45) = 1134903170 
Time elapsed: 33.530s 

A quelques centaines de millisecondes moins. Ce gain est dû à la prédiction de branchement assistée par programmateur.

Mais maintenant, pour ce que le programmeur doit vraiment faire au lieu:

~% gcc -O2 -Dopt= -fprofile-generate -o test.prof test.c 
~% ./test.prof 
... 
fib(45) = 1134903170 
Time elapsed: 77.530s /this run is slowed down by profile generation. 

~% gcc -O2 -Dopt= -fprofile-use -o test.good test.c 
~% ./test.good 
fib(45) = 1134903170 
Time elapsed: 17.760s 

Avec le profilage d'exécution assistée par le compilateur, nous avons réussi à réduire des 34.290s originaux à 17.760s. Beaucoup mieux qu'avec une prédiction de branche assistée par programmeur!

+1

l'utilisation du profil est la bonne option, mais je dois démontrer «probable» et «peu probable» – osgx

+19

aah, tm = -clock(); tm + = clock(); est belle, je ne l'ai pas vu avant, merci! –

+0

Je pense que ce que cela démontre est que "probable" et "improbable" ne sont pas très utiles. Aussi peut-être que c'est une implémentation vraiment mauvaise de 'fib()' ... –

Questions connexes