У меня есть код умножения матрицы, который выглядит так:
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;
}