이 세 동일한 연산을 수행 할 함수 고려 : (-03 -mavx)와GCC를 사용하여 더 나은 벡터화를 얻으려면 어떻게해야합니까?
#include <x86intrin.h>
void testfunc_loop(double a, double b, double* dst)
{
double f[] = {a,b,-a,-b};
for(int n = 0; n < 4; ++n)
{
dst[n] = 0.1 + f[n]*(1.0 + 0.5*f[n]);
}
}
void testfunc_flat(double a, double b, double* dst)
{
dst[0] = 0.1 + (a)*(1.0 + 0.5*(a));
dst[1] = 0.1 + (b)*(1.0 + 0.5*(b));
dst[2] = 0.1 + (-a)*(1.0 + 0.5*(-a));
dst[3] = 0.1 + (-b)*(1.0 + 0.5*(-b));
}
void testfunc_avx(double a, double b, double* dst)
{
__m256d one = _mm256_set1_pd(1.0);
__m256d half = _mm256_set1_pd(0.5);
__m256d tenth = _mm256_set1_pd(0.1);
__m256d v = _mm256_set_pd(-b,-a,b,a);
__m256d q = _mm256_add_pd(tenth,_mm256_mul_pd(v,_mm256_add_pd(one,_mm256_mul_pd(half,v))));
_mm256_store_pd(dst,q);
}
GCC 4.7.2 루프 버전을 벡터화하지만 펼쳐진 루프 스칼라 연산을 사용한다. 3 가지 버전에서 얻은 (정규화 된) 시간은 3.3 (루프, 자동 벡터화), 1.2 (언롤, 스칼라), 1 (수동 avx)입니다. 언 롤링 된 버전과 수동으로 벡터화 된 기능 간의 성능 차이는 작지만 전체 코드에서 유용하기 때문에 벡터화를 강제하고 싶습니다.
다른 컴파일러 (https://godbolt.org/g/HJH2CX 참조)에서 테스트 한 결과 clang은 풀린 루프를 자동으로 벡터화하지만 (버전 3.4.1부터) GCC는 버전 7까지 자동으로 벡터화합니다. GCC에서 자동으로 비슷한 벡터화를 사용할 수 있습니까? 루프 벡터화와 관련된 최적화 옵션이 도움이되지 않습니다. GCC website은 2011 년 이래로 소식이 없습니다.
누락 된 최적화에 대한 gcc의 버그질라 (bugzilla)에 문제를 제기하는 것이 합당한 방법입니다. 부정 여부가있는 표현식이 gcc와 너무 다르기 때문에 AVX 벡터화가 실패합니다.다른 한편, 그것은 SSE 벡터화를 거의 수행하지만 프롤로그 비용을 크게 과대 평가하기 때문에 수익성이없는 것으로 간주합니다 (사용량 - 비용 - 비용 모델 = 무제한 사용). 즉, 벡터 {a, b } 적어도 세 번, {1,1} 두 번 등). –
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78164 llvm은 gcc가 아니라 testfunc_flat의 SSE 벡터화를 얻습니다. –