Есть две программы перемножения матриц. Первая умножает «наивным» алгоритмом ijk, вторая - по ikj (по строкам).
mainijk.c
#include <stdio.h>
#include <stdlib.h>
const int SIZE = 512;
float * generateMatrix(float* a, int n)
{
int i, j;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
*(a + i*n + j) = (i - j)*(rand()/10000.0f);
}
}
return a;
}
float * multSquareMatrixIJK(float *a, float *b, float *c, int n)
{
int i, j, k;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
for (k = 0; k < n; k++)
{
*(c + i*n + j) += *(a + i*n + k) * *(b + k*n + j);
}
}
}
return c;
}
int main(int argc, char** argv)
{
float *a = calloc(SIZE*SIZE, sizeof(float));
float *b = calloc(SIZE*SIZE, sizeof(float));
float *c = calloc(SIZE*SIZE, sizeof(float));
generateMatrix(a, SIZE);
generateMatrix(b, SIZE);
multSquareMatrixIJK(a, b, c, SIZE);
free(c);
free(b);
free(a);
return 0;
}
mainikj.c
#include <stdio.h>
#include <stdlib.h>
const int SIZE = 512;
float * generateMatrix(float* a, int n)
{
int i, j;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
*(a + i*n + j) = (i - j) * (rand()/10000.0f);
}
}
return a;
}
float * multSquareMatrixIKJ(float *a, float *b, float *c, int n)
{
int i, j, k;
for (i = 0; i < n; i++)
{
for (k = 0; k < n; k++)
{
for (j = 0; j < n; j++)
{
*(c + i*n + j) += *(a + i*n + k) * *(b + k*n + j);
}
}
}
return c;
}
int main(int argc, char** argv)
{
float *a = calloc(SIZE*SIZE, sizeof(float));
float *b = calloc(SIZE*SIZE, sizeof(float));
float *c = calloc(SIZE*SIZE, sizeof(float));
generateMatrix(a, SIZE);
generateMatrix(b, SIZE);
multSquareMatrixIKJ(a, b, c, SIZE);
free(c);
free(b);
free(a);
return 0;
}
Внимание, вопрос.
muha@arch:matrix$ time ./ijk
./ijk 9,18s user 0,24s system 93% cpu 10,131 total
muha@arch:matrix$ time ./ikj
./ikj 0,55s user 0,01s system 89% cpu 0,619 total
Почему так, если фактически обе программы отличаются лишь переставленными циклами (т.е., количество циклов одно и то же).