我有一个矩阵乘法代码,如下所示:
for(i = 0; i < dimension; i++)
for(j = 0; j < dimension; j++)
for(k = 0; k < dimension; k++)
C[dimension*i+j] += A[dimension*i+k] * B[dimension*k+j];
在此,矩阵的大小由表示dimension
。现在,如果矩阵的大小为2000,则运行此代码需要147秒,而如果矩阵的大小为2048,则需要447秒。所以虽然没有区别。的乘积为(2048 * 2048 * 2048)/(2000 * 2000 * 2000)= 1.073,时间差为447/147 =3。有人可以解释为什么会这样吗?我希望它可以线性扩展,但不会发生。我不是在尝试制作最快的矩阵乘法代码,只是在试图理解为什么会这样。
规格:AMD Opteron双核节点(2.2GHz),2G RAM,gcc v 4.5.0
程序编译为 gcc -O3 simple.c
我也在英特尔的icc编译器上运行了此命令,并且看到了类似的结果。
编辑:
正如评论/答案中所建议的那样,我运行的维度为2060的代码需要145秒。
这是完整的程序:
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
/* change dimension size as needed */
const int dimension = 2048;
struct timeval tv;
double timestamp()
{
double t;
gettimeofday(&tv, NULL);
t = tv.tv_sec + (tv.tv_usec/1000000.0);
return t;
}
int main(int argc, char *argv[])
{
int i, j, k;
double *A, *B, *C, start, end;
A = (double*)malloc(dimension*dimension*sizeof(double));
B = (double*)malloc(dimension*dimension*sizeof(double));
C = (double*)malloc(dimension*dimension*sizeof(double));
srand(292);
for(i = 0; i < dimension; i++)
for(j = 0; j < dimension; j++)
{
A[dimension*i+j] = (rand()/(RAND_MAX + 1.0));
B[dimension*i+j] = (rand()/(RAND_MAX + 1.0));
C[dimension*i+j] = 0.0;
}
start = timestamp();
for(i = 0; i < dimension; i++)
for(j = 0; j < dimension; j++)
for(k = 0; k < dimension; k++)
C[dimension*i+j] += A[dimension*i+k] *
B[dimension*k+j];
end = timestamp();
printf("\nsecs:%f\n", end-start);
free(A);
free(B);
free(C);
return 0;
}
O(n^3)
。