SSE4 내적 제품으로이 코드를 개선하려고하지만 솔루션을 찾는 데 어려움을 겪고 있습니다. 이 함수는 각각 80 셀의 부동 배열을 포함하는 매개 변수 qi 및 tj를 얻은 다음 내적을 계산합니다. 반환 값은 네 점 곱을 갖는 벡터입니다. 그래서 제가하려고하는 것은 병렬로 20 개 값의 4 개 점 제품을 계산하는 것입니다.SSE4를 사용하여 점을 벡터화하는 작업
이 코드를 개선하는 방법에 대해 알고 계셨습니까?
inline __m128 ScalarProd20Vec(__m128* qi, __m128* tj)
{
__m128 res=_mm_add_ps(_mm_mul_ps(tj[0],qi[0]),_mm_mul_ps(tj[1],qi[1]));
res=_mm_add_ps(res,_mm_add_ps(_mm_mul_ps(tj[2],qi[2]),_mm_mul_ps(tj[3],qi[3])));
res=_mm_add_ps(res,_mm_add_ps(_mm_mul_ps(tj[4],qi[4]),_mm_mul_ps(tj[5],qi[5])));
res=_mm_add_ps(res,_mm_add_ps(_mm_mul_ps(tj[6],qi[6]),_mm_mul_ps(tj[7],qi[7])));
res=_mm_add_ps(res,_mm_add_ps(_mm_mul_ps(tj[8],qi[8]),_mm_mul_ps(tj[9],qi[9])));
res=_mm_add_ps(res,_mm_add_ps(_mm_mul_ps(tj[10],qi[10]),_mm_mul_ps(tj[11],qi[11])));
res=_mm_add_ps(res,_mm_add_ps(_mm_mul_ps(tj[12],qi[12]),_mm_mul_ps(tj[13],qi[13])));
res=_mm_add_ps(res,_mm_add_ps(_mm_mul_ps(tj[14],qi[14]),_mm_mul_ps(tj[15],qi[15])));
res=_mm_add_ps(res,_mm_add_ps(_mm_mul_ps(tj[16],qi[16]),_mm_mul_ps(tj[17],qi[17])));
res=_mm_add_ps(res,_mm_add_ps(_mm_mul_ps(tj[18],qi[18]),_mm_mul_ps(tj[19],qi[19])));
return res;
}
생각 해보니. 40 개의 메모리가로드됩니다. Sandy Bridge 프로세서를 사용하지 않는 한 40 사이클의 병목 현상이 발생합니다. 따라서 OP의 코드가 이미 최적 일 수 있습니다. – Mysticial
부동 소수점 연관성에 관하여 : 컴파일러 플래그'-phast-math'의 종종 저평가되고 오해 된 검은 양은 가끔은 이상하게 작동합니다. 그리고 AMD는 인류의 거의 새벽부터 사이클 당 두 개의 L1 메모리로드를 할 수 있지만 불행히도 다른 곳에서는 개가 느립니다. – hirschhornsalz
도움을 주셔서 대단히 감사드립니다. 내 테스트 결과에 의하면 내 코드는 아이디어만큼 빨리 작동한다고 나와 있습니다 (주석에서 언급 한대로). AMD FMA4는 재미있어 보이지만이 명령어는 내 컴퓨터에서 사용할 수 없으며 코드는 SSE2와 호환되어야합니다. 나는 그것을 절친한 수학으로 시도 할 것이다. –