我在 C 中使用 AVX2、FMA 制作了矩阵向量乘法程序。我使用带有 -mfma、-mavx 的 GCC ver7 编译。
但是,我收到错误“已释放对象的校验和不正确 - 对象可能在被释放后被修改”。
我认为如果矩阵维度不是 4 的倍数,则会产生错误。
我知道 AVX2 使用 ymm 寄存器,可以使用 4 个双精度浮点数。因此,如果矩阵是 4 的倍数,我可以毫无错误地使用 AVX2。
但是,这是我的问题。如果矩阵不是 4 的倍数,我如何有效地使用 AVX2 ???
这是我的代码。
#include "stdio.h"
#include "math.h"
#include "stdlib.h"
#include "time.h"
#include "x86intrin.h"
void mv(double *a,double *b,double *c, int m, int n, int l)
{
__m256d va,vb,vc;
int k;
int i;
for (k = 0; k < l; k++) {
vb = _mm256_broadcast_sd(&b[k]);
for (i = 0; i < m; i+=4) {
va = _mm256_loadu_pd(&a[m*k+i]);
vc = _mm256_loadu_pd(&c[i]);
vc = _mm256_fmadd_pd(vc, va, vb);
_mm256_storeu_pd( &c[i], vc );
}
}
}
int main(int argc, char* argv[]) {
// set variables
int m;
double* a;
double* b;
double* c;
int i;
int temp=0;
struct timespec startTime, endTime;
m=9;
// main program
// set vector or matrix
a=(double *)malloc(sizeof(double) * m*m);
b=(double *)malloc(sizeof(double) * m*1);
c=(double *)malloc(sizeof(double) * m*1);
for (i=0;i<m;i++) {
a[i]=1;
b[i]=1;
c[i]=0.0;
}
for (i=m;i<m*m;i++) {
a[i]=1;
}
// check start time
clock_gettime(CLOCK_REALTIME, &startTime);
mv(a, b, c, m, 1, m);
// check end time
clock_gettime(CLOCK_REALTIME, &endTime);
free(a);
free(b);
free(c);
return 0;
}