반응형
http://kerneltrap.org/node/4705
아래처럼 define 되는 likely라는 매크로가 있다.
#define likely(x) __builtin_expect((x),1) #define unlikely(x) __builtin_expect((x),0)
이것은 어떤 기능을 할까?
if (__builtin_expect (x, 0)) foo ();
위와같은 코드가 있다고 할 때, 컴파일러는 x가 0이 될 확률이 높다는걸 '알게'된다.
그럼 foo 함수를 실행할 가능성이 적어지고, 컴파일러가 최적화를 할 가능성이 커진다.
구체적인 예를 보자.
int
testfun(int x)
{
if(x) {
x = 5;
x = x * x;
} else {
x = 6;
}
return x;
}
함수 testfun은 인자 x로 어떤값이 들어올지 모른다.
레귤러하게 분포된다면,
x = 6이 될 확률은 1/2^32 이 될 것이다.
그러나, __builtin_expect()을 씀으로써, x는 '거의' 0임을 알려준다.
[kedar@ashwamedha ~]$ cat abc.c int testfun(int x) { if(__builtin_expect(x, 0)) { ^^^--- We instruct the compiler, "else" block is more probable x = 5; x = x * x; } else { x = 6; } return x; } [kedar@ashwamedha ~]$ gcc -O2 -c abc.c [kedar@ashwamedha ~]$ objdump -d abc.o abc.o: file format elf32-i386 Disassembly of section .text: 00000000 : 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 8b 45 08 mov 0x8(%ebp),%eax 6: 85 c0 test %eax,%eax 8: 75 07 jne 11 < testfun+0x11 > ^^^ --- The compiler branches the "if" block and keeps "else" sequential a: b8 06 00 00 00 mov $0x6,%eax f: c9 leave 10: c3 ret 11: b8 19 00 00 00 mov $0x19,%eax 16: eb f7 jmp f < testfun+0xf >
생성된 어셈블러를 보면 x가 0이 아닐 때 점프(jne)를 한다.
[kedar@ashwamedha ~]$ cat abc.c int testfun(int x) { if(__builtin_expect(x, 1)) { ^^^ --- We instruct the compiler, "if" block is more probable x = 5; x = x * x; } else { x = 6; } return x; } [kedar@ashwamedha ~]$ gcc -O2 -c abc.c [kedar@ashwamedha ~]$ objdump -d abc.o abc.o: file format elf32-i386 Disassembly of section .text: 00000000 : 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 8b 45 08 mov 0x8(%ebp),%eax 6: 85 c0 test %eax,%eax 8: 74 07 je 11 < testfun+0x11 > ^^^ --- The compiler branches the "else" block and keeps "if" sequential a: b8 19 00 00 00 mov $0x19,%eax f: c9 leave 10: c3 ret 11: b8 06 00 00 00 mov $0x6,%eax 16: eb f7 jmp f < testfun+0xf >
반대로, 위와 같은 경우엔 x가 0일 때 점프하게 된다.
Basic Block(코드의 순서)을 어떻게 배치하느냐에 따라서 성능은 달라 질 수있다.
(branch predictor가 없다면,) CPU는 PIPELINE으로 되있기 때문에 우선 branch는 무시하고, 있는 코드를 순서대로 실행하다 branch가 되야되면 파이프라인을 FLUSH시킨다. 그럼 성능이 떨어질 수 밖에 없다.
조그마한 성능도 중요한 임베디드나 커널 코드에 많이 쓰이는듯 하다.
반응형
'Program Language > C' 카테고리의 다른 글
LNK2005 already defined in LNK1169: one or more multiply defined symbols found (0) | 2012.11.27 |
---|---|
다차원 배열 (0) | 2012.10.03 |
#ifdef #else #endif #elifdef (0) | 2012.08.09 |
printf debugging (0) | 2012.06.19 |
sizeof (0) | 2012.06.04 |
댓글