У меня есть код умножения матриц это выглядит так:
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];
Здесь размер матрицы представлен как измерение
.
Теперь, если размер матриц равен 2000, запуск этого фрагмента занимает 147 секунд. кода, тогда как если размер матриц 2048, это занимает 447 секунд. Так что пока разницы ни в чём нет. умножений составляет (2048 * 2048 * 2048) / (2000 * 2000 * 2000) = 1.073, разница таймингов составляет 447/147 = 3. Может кто-нибудь объяснить, почему это происходит? Я ожидал, что он будет масштабироваться линейно, но этого не произошло. Я не пытаюсь сделать самый быстрый код умножения матриц, просто пытаюсь понять, почему это происходит.
Технические характеристики: двухъядерный узел AMD Opteron (2,2 ГГц), 2 ГБ ОЗУ, gcc v 4.5.0
Программа скомпилирована как gcc -O3 simple.c
Я запустил ее на компиляторе Intel 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;
}