4d 벡터를 정규화하려고합니다.SSE 정규화가 간단한 근사보다 느린가요?
내 첫 번째 승인은 내 벡터 산술에 2 배의 속도 향상을 제공하는 SSE 내장 함수를 사용하는 것이 었습니다. 다음은 기본 코드입니다 : (v.v4가 입력) (GCC를 사용하여) (이 모두가 인라인)
//find squares
v4sf s = __builtin_ia32_mulps(v.v4, v.v4);
//set t to square
v4sf t = s;
//add the 4 squares together
s = __builtin_ia32_shufps(s, s, 0x1B);
t = __builtin_ia32_addps(t, s);
s = __builtin_ia32_shufps(s, s, 0x4e);
t = __builtin_ia32_addps(t, s);
s = __builtin_ia32_shufps(s, s, 0x1B);
t = __builtin_ia32_addps(t, s);
//find 1/sqrt of t
t = __builtin_ia32_rsqrtps(t);
//multiply to get normal
return Vec4(__builtin_ia32_mulps(v.v4, t));
나는 분해를 확인하고 그것이 내가 기대하는 방법처럼 보인다. 거기에 큰 문제는 보이지 않습니다.
어쨌든, 그때 근사치를 사용하여 시도 : (내가 구글에서이있어) 그것은 SSE 버전보다 약간 더 빠르게 실행
float x = (v.w*v.w) + (v.x*v.x) + (v.y*v.y) + (v.z*v.z);
float xhalf = 0.5f*x;
int i = *(int*)&x; // get bits for floating value
i = 0x5f3759df - (i>>1); // give initial guess y0
x = *(float*)&i; // convert bits back to float
x *= 1.5f - xhalf*x*x; // newton step, repeating this step
// increases accuracy
//x *= 1.5f - xhalf*x*x;
return Vec4(v.w*x, v.x*x, v.y*x, v.z*x);
! (약 5-10 % 빠름) 결과도 매우 정확합니다. 길이를 찾으면 0.001로 말할 것입니다! 하지만 .. GCC는 타입 펀칭 때문에 절름발이의 엄격한 앨리어싱 규칙을 제공하고 있습니다. 이제 (경고없이) 수정 된 버전 를 느리게 실행을
union {
float fa;
int ia;
};
fa = (v.w*v.w) + (v.x*v.x) + (v.y*v.y) + (v.z*v.z);
float faHalf = 0.5f*fa;
ia = 0x5f3759df - (ia>>1);
fa *= 1.5f - faHalf*fa*fa;
//fa *= 1.5f - faHalf*fa*fa;
return Vec4(v.w*fa, v.x*fa, v.y*fa, v.z*fa);
을 그리고! :
그래서 나는 그것을 수정 SSE 버전이 실행되는 속도의 거의 60 %가 실행됩니다 (그러나 같은 결과)! 왜 이런거야?
- 내 SSE의 implentation 맞 : 그래서 여기
는 질문 (들)입니까?
- SSE는 일반적인 fpu 작업보다 실제로 느린가요?
- 왜 제 3의 코드가 그렇게 느린가요?
사용중인 CPU를 알고 있으면 도움이됩니다. 예 : 오래된 x86 CPU (pre Core 2)는 SSE 기능이 매우 좋지 않습니다. –
인텔 펜티엄 듀얼 코어 – Pubby
중복 http://stackoverflow.com/questions/1528727/why-is-sse-scalar-sqrtx-slower-than-rsqrtx-x? – celion