2013-03-27 6 views
1

Следующие два фрагмента кода создают точно такой же код сборки, даже если ветви заключены в разные предсказания ветвлений.gcc __builtin_expect, похоже, не генерирует правильный код

Давайте предположим, что мы имеем test0.c

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

int bar0(); 
int bar1(); 
int bar2(); 
int bar3(); 

int foo(int arg0) { 
    if (likely(arg0 > 100)) { 
    return bar0(); 
    } else if (likely(arg0 < -100)) { 
    return bar1(); 
    } else if (likely(arg0 > 0)) { 
    return bar2(); 
    } else { 
    return bar3(); 
    } 
} 

и test1.c

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

int bar0(); 
int bar1(); 
int bar2(); 
int bar3(); 

int foo(int arg0) { 
    if (unlikely(arg0 > 100)) { 
    return bar0(); 
    } else if (unlikely(arg0 < -100)) { 
    return bar1(); 
    } else if (unlikely(arg0 > 0)) { 
    return bar2(); 
    } else { 
    return bar3(); 
    } 
} 

Как вы можете видеть, сравнивая два фрагмента, эти две разные предсказания ветвления для каждая ветвь (вероятно() против маловероятной()).

Однако, когда он скомпилирован из linux box (ubuntu 12.04 32bit, gcc 4.6.3). Эти два источника дают практически одинаковые результаты.

$gcc -c -S -o test0.s test0.c 
$gcc -c -S -o test1.s test1.c 
$ diff test0.s test1.s 
1c1 
< .file "test0.c" 
--- 
> .file "test1.c" 

Если кто-нибудь может это объяснить, это будет большой помощью. Спасибо за вашу помощь заранее!

ответ

2

Два файла, которые вы опубликовали, идентичны - я полагаю, это не то, что вы действительно сделали.

Скомпилируйте с помощью -O2 или выше, вам нужно включить оптимизацию. Затем он должен генерировать другой код.

+0

Да, вы правы! И я также исправил код. Большое спасибо за вашу помощь! – kjee

+1

@ user1036234 - добро пожаловать – teppic

Смежные вопросы