저는 이제 SIMD를 배우고 컴파일러가 내 코드를 더 잘 최적화 할 수있는 방법을 생각하고 있습니다. 이제 Visual C++ 2013 x86을 사용하고 있습니다. 오버레이되지어떻게하면 VC 컴파일러가 SIMD로 내 코드를 최적화 할 수 있을까요?
void computeSum(float* __restrict arr, float* __restrict inp1, float* __restrict inp2, int count)
{
__declspec(align(16)) float* p1 = inp1;
__declspec(align(16)) float* p2 = inp2;
__declspec(align(16)) float* ret = arr;
while (count > 0)
{
ret[0] = p1[0] + p2[0];
ret[1] = p1[1] + p2[1];
ret[2] = p1[2] + p2[2];
ret[3] = p1[3] + p2[3];
p1 += 4;
p2 += 4;
ret += 4;
count -= 4;
}
}
을 내가 배열은 16 바이트 경계 누구나 정렬됩니다 컴파일러를 말하고 싶은 :
내가 배열을 가지고, 나는 다른 배열을 가지고, 나는 다음과 같이 계산하려면 하나의 루프는 4 개의 연속 부동 소수점 합계를 계산합니다.
그러나 생성 된 코드에서 VC는 MOVSS/ADDSS보다 선호하며 ADDPS를 사용하지 않습니다.
프로젝트를 LLVM-vs2013 툴 체인을 사용하도록 구성하면 ADDPS를 사용하여 합계를 계산합니다.
나는 컴파일러 내장 함수를 사용하여 SIMD 코드를 작성하는 방법을 알고 있지만 그게 내가 원하는 것은 아니다.
VC가 ADDPS 명령어를 사용해야한다는 힌트가 더 있습니까?
이것은 전체 코드입니다.
#include <stdio.h>
#include <stdlib.h>
void computeSum(float* __restrict arr, float* __restrict inp1, float* __restrict inp2, int count)
{
__declspec(align(16)) float* p1 = inp1;
__declspec(align(16)) float* p2 = inp2;
__declspec(align(16)) float* ret = arr;
while (count > 0)
{
ret[0] = p1[0] + p2[0];
ret[1] = p1[1] + p2[1];
ret[2] = p1[2] + p2[2];
ret[3] = p1[3] + p2[3];
p1 += 4;
p2 += 4;
ret += 4;
count -= 4;
}
}
int main()
{
float* inp1 = (float*)_aligned_malloc(sizeof(float) * 128, 16);
float* inp2 = (float*)_aligned_malloc(sizeof(float) * 128, 16);
float* result = (float*)_aligned_malloc(sizeof(float) * 128, 16);
for (int i = 0; i < 128; ++i)
{
inp1[i] = inp2[i] = i;
}
computeSum(result, inp1, inp2, 128);
for (int i = 0; i < 128; ++i)
{
printf("%f\t", result[i]);
}
return 0;
}
/arch : SSE (또는 이와 유사)를 지정 했습니까? – harold
@harold 예 스위치/arch : SSE2가 사용 가능합니다. – Sorayuki
루프를 풀지 * 않으려 고 시도 했습니까? –