У меня есть код умножения матрицы, который выглядит так:
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 node (2,2 ГГц), 2 Гб оперативной памяти, gcc v 4.5.0
Программа скомпилирована как gcc -O3 simple.c
Я тоже запустил это на компиляторе Intel icc и увидел похожие результаты.
EDIT:
Как было предложено в комментариях/ответах, я запустил код с размером = 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;
}