Aprovechese de Spatial Locality
En C, matrices se almacenan en r ow-major order. Por lo tanto, si accede al elemento a[i][j]
, es probable que un acceso al elemento a[i][j+1]
llegue al caché. No se realizará ningún acceso a la memoria principal. Los cachés son más rápidos que la memoria principal, por lo que el patrón de acceso sí importa.
Por supuesto, se deben tener en cuenta otros factores, como el acceso de escritura/lectura, la política de escritura (escritura, escritura/asignación de escritura, asignación de escritura), cachés multinivel, etc. Pero eso parece una exageración para esta pregunta.
Diviértete con una herramienta de creación de perfiles, como cachegrind, y compruébalo por ti mismo.
Por ejemplo, considere un programa ficticio que acceda a matrices de 4MB. Verifique las diferencias entre las tasas de error en cada patrón de acceso.
acceso a la columna
$ 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% )
acceso a filas
$ 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% )
¿Qué idioma estás usando? Los diferentes lenguajes tienen representaciones diferentes para las matrices, y eso afecta cómo deberían usarse. – Karmastan
estoy usando el lenguaje c –