我目前正在堆上实现floats
的N x 2矩阵,如下所示:
float **matrix = malloc(sizeof(float*) * n_cols);
for (int i = 0; i < n_cols; ++i) {
matrix[i] = malloc(sizeof(float) * 2);
}
matrix
的元素在内存中不连续,这使得这种数据结构缓存不友好(正如我所理解的)。我正试图重写上面的内容,以便在堆上创建一个真正的2D阵列。基于之前的一些SO帖子,我尝试了以下内容:
float (*matrix)[2] = malloc(sizeof(float) * n_cols * 2);
然而,当我运行代码时,这会导致分段错误。
如果希望整个数组是连续的,则需要如下声明。
float *matrix = malloc(n1 * n2 * sizeof(float));
这有帮助吗。请注意矩阵的第二种分配方式。
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
size_t r = 0;
size_t c = 0;
int rows = 82;
int columns = 30;
float *matrix = malloc(rows * columns * sizeof(float));
for(r = 0; r < rows; r++) {
printf("%zu - ", r);
for(c = 0; c < columns; c++) {
printf("%zu|", c);
matrix[r + r*c] = 1.0;
}
printf("n");
}
float **matrix2 = malloc(rows * sizeof(float*));
for(r = 0; r < rows; r++) {
matrix2[r] = malloc(columns * sizeof(float));
}
for(r = 0; r < rows; r++) {
printf("%zu - ", r);
for(c = 0; c < columns; c++) {
printf("%zu|", c);
matrix2[r][c] = 1.0;
}
printf("n");
}
free(matrix);
for(r = 0; r < rows; r++) {
free(matrix2[r]);
}
free(matrix2);
return 0;
}
你可以在这里找到一个带有代码的基准。。。
https://github.com/harryjackson/doc/blob/master/c/cache_locality_2d_array_test.c
我想你想要这样的东西。
float ** matrix = malloc(sizeof(float) * ((n_col * 2) + (n_col * sizeof(float*));
for(i = 0; i < n_col; i++)
{
matrix[i] = matrix + (n_col *sizeof(float*)) + ((i * 2) *sizeof(float));
}
矩阵的大小是2*n_col,但是矩阵的第一个索引将是指向列的指针。您必须为这些指针分配额外的空间。这就是(n_col*sizeof(float*))发挥作用的地方。每一行的大小都是(2*sizeof(float)),因此矩阵中第一个索引的每一行都需要指向距离最后一个字节的内存数组(2*sizeof(浮点))。
它看起来像这样。
m[0]m[1]m[2]矩阵矩阵+1*(2*sizeof(float))矩阵+2*(2*size of(floot))
第二个索引遵循由m[x]指向的存储器中的一个位置。