당연히 포함할 줄 알았는디.. 아니었구나.
물론 gcc 버전따라, arch따라 다를 것이다. 실험환경은 i7-7700, 3.6Ghz, 우분투 18.04, gcc 7.3.0이다.
추가적으로, 임베디드에서는 코드 사이즈를 1바이트라도 아낄 것이냐 속도를 0.001초라도 당길 것이냐 고민할 필요가 있다.
#include <stdio.h>
int main()
{
long int count = 0;
long int i, j;
long int kk[4];
for (i = 0; i < 4; i++) {
kk[i] = (i + 1) * 3;
}
for (i = 0; i < 100000; i++) {
for (j = 0; j < 100000; j++) {
count += i * 2 + j + 100 + kk[j % 4];
}
}
printf("%ld\n", count);
return 0;
}
gcc -o unr unr.c -O3 -march=skylake -funroll-loops : 3.910초
gcc -o unr unr.c -O3 -march=skylake : 5.085초
gcc -o unr unr.c -O3 : 5.077초
gcc -o unr unr.c : 19.308초
소요 시간 차이가 적은 놈들은 코드 안에서 시간을 직접 재고 평균을 써야 한다. 분기 예측에 관한 내용은 꽤 복잡해서 어떤 상황에서 얼마나 잘 동작하는지는 모르겠지만, unroll-loops만으로도 저 정도의 성능 향상이 있다는 것은 저 정도의 산수만 등장해도 파이프가 깨지는 구간이 있을 것으로 추정된다.
쿠다 문서를 보다가 문득 cuda와 ARM에는 #pragma unroll
이 있어서 설마 하고 실험해보았는데 턱하고 차이가 난다.