2010-04-29 4 views
10

Как продемонстрировать для студентов удобство использования likely и unlikely подсказки компилятора (__builtin_expect)?учебный пример вероятных() и маловероятных() подсказок компилятора

Можете ли вы написать пример кода, который будет в несколько раз быстрее с этими подсказками, сравнивая код без подсказок.

+2

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

+0

@ T.J. Кроудер, да. но мне нужен образец программы, в котором учащиеся могут ЧУВСТВОВАТЬ разницу, а не читать ее на ассемблере. – osgx

+1

@osgx: Вы не получите такой образец, потому что нет никакой разницы. Это худший, самый уродливый вид бесполезной микро-оптимизации. –

ответ

22

Вот один я использую, очень неэффективен реализация чисел Фибоначчи:

#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; 
} 

Чтобы продемонстрировать, используя 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 

Несколько сотен миллисекунд меньше. Это усиление связано с предсказанием программируемой ветви.

Но теперь, за что программист должен действительно делать вместо этого:

~% 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 

С компилятором автоматизированного выполнения профилирования, нам удалось сократить от первоначальных 34.290s до 17.760s. Гораздо лучше, чем с предсказанием программистской ветви!

+1

использование профиля - хороший вариант, но мне нужно продемонстрировать 'вероятно' и' маловероятно' – osgx

+19

aah, tm = -clock(); tm + = clock(); красивый, я не видел его раньше, спасибо! –

+0

Я думаю, что это демонстрирует, что «вероятно» и «маловероятно» не очень полезны. Также возможно, что это действительно плохая реализация 'fib()' ... –