[英]Matrix multiplication using SSE intrinsics
我正在嘗試使用SSE進行Matrix乘法。 我為4x4矩陣編寫了一個簡單的程序。 一切似乎都很好但是當我打印結果時,它的一些垃圾值。 請幫助找出問題/ s。 其次程序在我釋放內存時停止工作,而不是正確的程序結束。
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <float.h>
#include <xmmintrin.h>
void main() {
float **a, **b, **c;
int a_r = 4, a_c = 4, b_c = 4, b_r = 4;
int i, j, k;
/* allocate memory for matrix one */
a = (float **)malloc(sizeof(float) * a_r);
for (i = 0; i < a_c; i++) {
a[i] = (float *)malloc(sizeof(float) * a_c);
}
/* allocate memory for matrix two */
b = (float **)malloc(sizeof(float) * b_r);
for (i = 0; i < b_c; i++) {
b[i] = (float *)malloc(sizeof(float) * b_c);
}
/* allocate memory for sum matrix */
c = (float **)malloc(sizeof(float) * a_r);
for (i = 0; i < b_c; i++) {
c[i] = (float *)malloc(sizeof(float) * b_c);
}
printf("Initializing matrices...\n");
//initializing first matrix
for (i = 0; i < a_r; i++) {
for (j = 0; j < a_c; j++) {
a[i][j] = 2;
}
}
// initializing second matrix
for (i = 0; i < b_r; i++) {
for (j = 0; j < b_c; j++) {
b[i][j] = 2;
}
}
/* initialize product matrix */
for (i = 0; i < a_r; i++) {
for (j = 0; j < b_c; j++) {
c[i][j] = 0;
}
}
int count = 0;
/* multiply matrix one and matrix two */
for (i = 0; i < a_r; i++) {
for (j = 0; j < a_c; j++) {
count = 0;
__m128 result = _mm_setzero_ps();
for (k = 0; k < 4; k += 4) {
__m128 row1 = _mm_loadu_ps(&a[i][k]);
__m128 row2 = _mm_loadu_ps(&b[k][j]);
result = _mm_mul_ps(row1, row2);
for (int t = 1; t < 4; t++) {
__m128 row3=_mm_loadu_ps(&a[t * 4]);
__m128 row4=_mm_loadu_ps(&b[i][t]);
__m128 row5 = _mm_mul_ps(row3,row4);
result = _mm_add_ps(row5, result);
}
_mm_storeu_ps(&c[i][j], result);
}
}
}
printf("******************************************************\n");
printf ("Done.\n");
for (i = 0; i < a_r ; i++) {
for (j = 0; j < b_c; j++) {
printf ("%f ", c[i][j]); // issue here when I print results.
}
printf("\n");
} // Here program stops working.
/*free memory*/
for (i = 0; i < a_r; i++) {
free(a[i]);
}
free(a);
for (i = 0; i < a_c; i++) {
free(b[i]);
}
free(b);
for (i = 0; i < b_c; i++) {
free(c[i]);
}
free(c);
}
請查看為輸出矩陣打印的地址。 如何獲得對齊的地址,我有_aligned_malloc
,但仍然沒有對齊。
矩陣間接指針的分配是不正確的。 它應該是:
a = (float **)malloc(sizeof(float*) * a_r);
編寫這些分配的更安全的方法是:
a = malloc(sizeof(*a) * a_r);
請注意,您可以直接分配2D矩陣:
float (*a)[4][4] = malloc(sizeof(*a));
或者更好,正如Cody Gray建議的那樣:
float (*a)[4][4] = _aligned_malloc(sizeof(*a));
_aligned_malloc
是一個非標准函數,可確保SSE操作數的正確對齊。
如果您甚至不需要使用malloc()
分配這些矩陣:
float a[4][4];
但是對於后一種選擇,您必須確保正確對齊SSE操作才能成功。
其余代碼還有其他問題:
void main()
不正確。 它應該是int main(void)
第二個矩陣操作數應該轉置,這樣您就可以一次讀取多個值。 第二次加載將變為:
__m128 row2 = _mm_loadu_ps(&b[j][k]);
總和階段似乎也是錯誤的。 最后的商店絕對不正確,應該只是:
c[i][j] = sum;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.