C 使用SSE内部函数的矩阵乘法
我正在尝试使用SSE进行矩阵乘法。我已经为4x4矩阵编写了一个简单的程序。一切似乎都很好,但当我打印结果时,它是一些垃圾值。请帮助解决问题。第二,当我释放内存时,程序停止工作,这不是程序的正确结束C 使用SSE内部函数的矩阵乘法,c,sse,simd,C,Sse,Simd,我正在尝试使用SSE进行矩阵乘法。我已经为4x4矩阵编写了一个简单的程序。一切似乎都很好,但当我打印结果时,它是一些垃圾值。请帮助解决问题。第二,当我释放内存时,程序停止工作,这不是程序的正确结束 #include <stdlib.h> #include <stdio.h> #include <time.h> #include <float.h> #include <xmmintrin.h> void main() { flo
#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);
}
#包括
#包括
#包括
#包括
#包括
void main(){
浮动**a、**b、**c;
int a_r=4,a_c=4,b_c=4,b_r=4;
int i,j,k;
/*为矩阵1分配内存*/
a=(浮动**)malloc(浮动)*a\u r;
对于(i=0;i
请查看输出矩阵打印的地址。如何获得对齐的地址,我有\u aligned\u malloc
,但仍然没有对齐
矩阵间接指针的分配不正确。应改为:
a = (float **)malloc(sizeof(float*) * a_r);
编写这些分配的更安全的方法是:
a = malloc(sizeof(*a) * a_r);
请注意,您可以直接分配二维矩阵:
float (*a)[4][4] = malloc(sizeof(*a));
或者更好,正如科迪·格雷所说:
float (*a)[4][4] = _aligned_malloc(sizeof(*a));
\u aligned\u malloc
是一个非标准函数,可确保SSE操作数正确对齐
如果您甚至不需要使用malloc()
分配这些矩阵:
但对于后一种选择,您必须确保苏格兰和南方能源公司运营的成功与否
代码的其余部分还有其他问题:
不正确。它应该是void main()
int main(void)
- 第二个矩阵操作数应进行转置,以便一次可以读取多个值。第二个负载将变成:
__m128 row2 = _mm_loadu_ps(&b[j][k]);
- 求和阶段似乎也不正确。最终的存储肯定是错误的,应该是:
c[i][j] = sum;
\u mm\u loadu\u ps
和\u mm\u storeu\u ps
,则不需要使用Google。在分配指针数组时,您使用了错误的大小。停止强制转换malloc。它隐藏了错误。您最好在SIMD代码中使用\u aligned\u malloc
。
c[i][j] = sum;