SSE 내장 함수로 작업 한 것은 이번이 처음입니다. 인텔 SSE 내장 (SSE4.2까지)을 사용하여 간단한 코드를 더 빠른 버전으로 변환하려고합니다. 나는 많은 오류가 발생하는 것 같습니다.인텔 SSE 내장 함수를 사용하여 코드를 최적화하는 코드
코드의 스칼라 버전은 다음과 같습니다 (단순 행렬 곱셈)
void mm(int n, double *A, double *B, double *C)
{
int i,j,k;
double tmp;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++) {
tmp = 0.0;
for(k = 0; k < n; k++)
tmp += A[n*i+k] *
B[n*k+j];
C[n*i+j] = tmp;
}
}
이 내 버전입니다 : 내가
void mm_sse(int n, double *A, double *B, double *C)
{
int i,j,k;
double tmp;
__m128d a_i, b_i, c_i;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++) {
tmp = 0.0;
for(k = 0; k < n; k+=4)
a_i = __mm_load_ps(&A[n*i+k]);
b_i = __mm_load_ps(&B[n*k+j]);
c_i = __mm_load_ps(&C[n*i+j]);
__m128d tmp1 = __mm_mul_ps(a_i,b_i);
__m128d tmp2 = __mm_hadd_ps(tmp1,tmp1);
__m128d tmp3 = __mm_add_ps(tmp2,tmp3);
__mm_store_ps(&C[n*i+j], tmp3);
}
}
이 어디에서 잘못이와 함께 갈거야 인클루드 포함했다? I는 다음과 같이 여러 가지 오류를 얻고 :
mm_vec.c (84) : 오류 : 타입의 값이 "INT"N "__m128d" A_I = __mm_load_ps (& A [형 엔티티에 할당 될 수 없다 * I + k]);
이 내가 컴파일하고 방법은 다음과 같습니다 ICC -O2 mm_vec.c -o VEC
누군가가 정확하게이 코드를 변환하는 저를 도와 주시겠습니까. 감사!
UPDATE :
void mm_sse(int n, float *A, float *B, float *C)
{
int i,j,k;
float tmp;
__m128 a_i, b_i, c_i;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++) {
tmp = 0.0;
for(k = 0; k < n; k+=4)
a_i = _mm_load_ps(&A[n*i+k]);
b_i = _mm_load_ps(&B[n*k+j]);
c_i = _mm_load_ps(&C[n*i+j]);
__m128 tmp1 = _mm_mul_ps(a_i,b_i);
__m128 tmp2 = _mm_hadd_ps(tmp1,tmp1);
__m128 tmp3 = _mm_add_ps(tmp2,tmp3);
_mm_store_ps(&C[n*i+j], tmp3);
}
}
을하지만 지금은 분할 오류를 받고있는 것으로 보인다 :
는 귀하의 제안에 따라, 나는 다음과 같은 변화를 만들었습니다. 배열 A, B, C에 대해 배열 첨자에 제대로 액세스하지 않기 때문에이 사실을 알고있을 것입니다. 나는 이것에 아주 새롭고, 이것을 계속하는 방법을 모르겠습니다.
이 코드를 올바르게 처리하는 방법을 결정하는 데 도움을주십시오.
저는 gcc가 아닌 icc로 작업하고 있습니다. a_i = _mm_load_ps (& A [n * i + k]);가 올바른 접근 방법이라고 생각하십니까? 필자가 다른 곳에 게시 한 예 (인텔 내장 문서에도 있음)에는 매우 기본적인 예제가 있습니다. 배열 A, B, C는 모두 malloc으로 할당되었습니다. – PGOnTheGo
@Hello_PG로드 자체가 잘못되었습니다. 하지만 c_i를로드 할 필요는 없습니다. 대부분의 경우 ICC는 gcc와 동일한 확장 기능을 가지고 있습니다. 저는 이것이 정렬을위한 경우라고 생각합니다. ICC보다는 개인적으로 GCC에 더 익숙해 졌기 때문에 저는 그것을 자격을 얻었고 찾을 방법을 알고있는 문서에 링크되었습니다. malloc은 모든 플랫폼에서 적절한 정렬을 보장하지 않으므로 posix_memalign이 필요할 것입니다. 내가 제안한 주장이 실패 했나요? – Flexo
A와 같이 메모리를 할당하려고하면 A = (float *) _ aligned_malloc (dimension * dimension * sizeof (float), 16); 컴파일 오류가 발생합니다 : icc로'aligned_malloc '에 대한 참조가 정의되지 않았습니다. 이것은 컴파일하는 방법입니다. icc -O2 mm_vec.c -o vec2 – PGOnTheGo