Матричное умножение: небольшая разница в размере матрицы, большая разница во времени

У меня есть код умножения матриц это выглядит так:

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;
}
74
задан Mysticial 8 January 2012 в 22:52
поделиться