Примите преимущество Spatial Locality
В C, матрицы хранятся в г ow-major order. Поэтому, если вы обращаетесь к элементу a[i][j]
, доступ к элементу a[i][j+1]
, вероятно, попадет в кэш. Не будет доступа к основной памяти. Кэш-память быстрее, чем основная память, поэтому шаблон доступа имеет значение.
Разумеется, необходимо учитывать большее количество факторов, таких как доступ на запись/чтение, политика записи (запись, запись назад/запись, отсутствие выделения записи), многоуровневые кэши и т. Д. Но это кажется излишним для этого вопроса.
Поудобьте с помощью профилирующего инструмента, такого как cachegrind, и посмотрите его сами.
Например, рассмотрим фиктивную программу, имеющую 4 МБ матрицы. Проверьте различия между значениями пропуска по каждому шаблону доступа.
доступ колонка
$ cat col_major.c
#include <stdio.h>
int main(){
size_t i,j;
const size_t dim = 1024 ;
int matrix [dim][dim];
for (i=0;i< dim; i++){
for (j=0;j <dim;j++){
matrix[j][i]= i*j;
}
}
return 0;
}
$ valgrind --tool=cachegrind ./col_major
==3228== D refs: 10,548,665 (9,482,149 rd + 1,066,516 wr)
==3228== D1 misses: 1,049,704 ( 968 rd + 1,048,736 wr)
==3228== L2d misses: 1,049,623 ( 893 rd + 1,048,730 wr)
==3228== D1 miss rate: 9.9% ( 0.0% + 98.3% )
==3228== L2d miss rate: 9.9% ( 0.0% + 98.3% )
доступа ряд
$ cat row_major.c
#include <stdio.h>
int main(){
size_t i,j;
const size_t dim = 1024 ;
int matrix [dim][dim];
for (i=0;i< dim; i++)
for (j=0;j <dim;j++)
matrix[i][j]= i*j;
return 0;
}
$ valgrind --tool=cachegrind ./row_major
==3524== D refs: 10,548,665 (9,482,149 rd + 1,066,516 wr)
==3524== D1 misses: 66,664 ( 968 rd + 65,696 wr)
==3524== L2d misses: 66,583 ( 893 rd + 65,690 wr)
==3524== D1 miss rate: 0.6% ( 0.0% + 6.1% )
==3524== L2d miss rate: 0.6% ( 0.0% + 6.1% )
Какой язык вы используете? Различные языки имеют разные представления для матриц, и это влияет на то, как они должны использоваться. – Karmastan
Я использую язык c –