[t:/]$ 지식_

gcc O3는 unroll-loops를 포함하지 않는다.

2018/09/19

당연히 포함할 줄 알았는디.. 아니었구나.
물론 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이 있어서 설마 하고 실험해보았는데 턱하고 차이가 난다.









[t:/] is not "technology - root". dawnsea, rss