我目前正在堆上实现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);
但是,当我运行代码时,这会导致分段错误。
答案 0 :(得分: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
答案 1 :(得分:0)
我想你想要这样的东西。
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(float))字节。
它看起来像这样。
m [0] m [1] m [2] 矩阵矩阵+ 1 *(2 * sizeof(float))矩阵+ 2 *(2 * sizeof(float))
第二个索引将m [x]指向的内存位置引入内存。