내장 함수가 SIMD를 일반 매트릭스 곱셈보다 느리게 만드는 것은 무엇이며 SIMD를 사용하여 더 빠르게 대 매트릭스의 곱셈을 만들려면 어떻게해야하는지 궁금합니다. 여기에 matrixA[8][8]
, matrixB[8][8]
및 결과 matrixC[8][8]
이 있습니다. float32_t의 최대 요소 수는 4이므로 2 개의 vmul 및 vadd를 수행 했으므로 최적화되지 않은 것 같습니다. 저는 ARMv7-A Cortex A8에서 작업합니다.8x8 float32_t ARM NEON을 사용하는 행렬 곱셈 속도가 느립니까?
void matrix_mult_neon (void)
{
int i;
float32x4x2_t vectB1, vectB2, vectB3, vectB4, vectB5, vectB6, vectB7, vectB8;
vectB1 = vld2q_f32(matrixB[0]);
vectB2 = vld2q_f32(matrixB[1]);
vectB3 = vld2q_f32(matrixB[2]);
vectB4 = vld2q_f32(matrixB[3]);
vectB5 = vld2q_f32(matrixB[4]);
vectB6 = vld2q_f32(matrixB[5]);
vectB7 = vld2q_f32(matrixB[6]);
vectB8 = vld2q_f32(matrixB[7]);
float32x4x2_t vectT1, vectT2, vectT3, vectT4, vectT5, vectT6, vectT7, vectT8;
for (i = 0; i < 8; i++)
{
vectT1.val[0] = vmulq_n_f32(vectB1.val[0], matrixA[i][0]);
vectT1.val[1] = vmulq_n_f32(vectB1.val[1], matrixA[i][0]);
vectT2.val[0] = vmulq_n_f32(vectB2.val[0], matrixA[i][1]);
vectT2.val[1] = vmulq_n_f32(vectB2.val[1], matrixA[i][1]);
vectT3.val[0] = vmulq_n_f32(vectB3.val[0], matrixA[i][2]);
vectT3.val[1] = vmulq_n_f32(vectB3.val[1], matrixA[i][2]);
vectT4.val[0] = vmulq_n_f32(vectB4.val[0], matrixA[i][3]);
vectT4.val[1] = vmulq_n_f32(vectB4.val[1], matrixA[i][3]);
vectT5.val[0] = vmulq_n_f32(vectB5.val[0], matrixA[i][4]);
vectT5.val[1] = vmulq_n_f32(vectB5.val[1], matrixA[i][4]);
vectT6.val[0] = vmulq_n_f32(vectB6.val[0], matrixA[i][5]);
vectT6.val[1] = vmulq_n_f32(vectB6.val[1], matrixA[i][5]);
vectT7.val[0] = vmulq_n_f32(vectB7.val[0], matrixA[i][6]);
vectT7.val[1] = vmulq_n_f32(vectB7.val[1], matrixA[i][6]);
vectT8.val[0] = vmulq_n_f32(vectB8.val[0], matrixA[i][7]);
vectT8.val[1] = vmulq_n_f32(vectB8.val[1], matrixA[i][7]);
vectT1.val[0] = vaddq_f32(vectT1.val[0], vectT2.val[0]);
vectT1.val[0] = vaddq_f32(vectT1.val[0], vectT3.val[0]);
vectT1.val[0] = vaddq_f32(vectT1.val[0], vectT4.val[0]);
vectT1.val[0] = vaddq_f32(vectT1.val[0], vectT5.val[0]);
vectT1.val[0] = vaddq_f32(vectT1.val[0], vectT6.val[0]);
vectT1.val[0] = vaddq_f32(vectT1.val[0], vectT7.val[0]);
vectT1.val[0] = vaddq_f32(vectT1.val[0], vectT8.val[0]);
vectT1.val[1] = vaddq_f32(vectT1.val[1], vectT2.val[1]);
vectT1.val[1] = vaddq_f32(vectT1.val[1], vectT3.val[1]);
vectT1.val[1] = vaddq_f32(vectT1.val[1], vectT4.val[1]);
vectT1.val[1] = vaddq_f32(vectT1.val[1], vectT5.val[1]);
vectT1.val[1] = vaddq_f32(vectT1.val[1], vectT6.val[1]);
vectT1.val[1] = vaddq_f32(vectT1.val[1], vectT7.val[1]);
vectT1.val[1] = vaddq_f32(vectT1.val[1], vectT8.val[1]);
vst2q_f32(matrixC_neon[i], vectT1);
}
}
내 정규 행렬 곱셈 함수 :
void matrix_mult (void)
{
float tempProduct;
int i, j, k;
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
tempProduct = 0;
for (k = 0; k < 8; k++)
{
tempProduct = tempProduct + matrixA[i][k] * matrixB[k][j];
}
matrixC[i][j] = tempProduct;
}
}
}
I 나노초 시간을 계산하기 위해 라이브러리에 <sys/time.h>
gettimeofday()
함수를 사용한다.
무엇보다 천천히? 그리고 정확히 정확한 ARM 칩과 컴파일러 옵션은 무엇입니까? 어쩌면 컴파일러가 수동으로 벡터화 한 것보다 자동 벡터화 된 것이 더 나은 것일 수 있습니다. 또한 정확히 얼마나 시간을 보냈습니까? –
나는 분명히하기 위해 게시물을 편집했습니다. 내가 알고 싶은 것은 NEON 함수에서 어디에서 잘못 했습니까, 아니면 충분히 최적화하지 않았습니까? –
어떤 컴파일러를 사용했으며 어떤 옵션이 있습니까? ''양산 '을 사용하셨습니까? (NEON FP는 IEEE와 완전히 호환되지 않습니다. 컴파일러가 스칼라에'-ffast-math'를 쓰지 않고 컴파일 할 수 있습니다.) –