在 C 中:访问像二维数组一样使用的 char* = malloc() 是否比访问数组 [][] 更快?
In C: Is it faster to access a char* = malloc() used like a 2D array than an array[][]?
刚刚偶然发现了这个最近的问题:
How can I have a dynamically allocated 2D array in C?
我只是想知道:当我用一个简单的 malloc 创建一个 2D 数组并像这样自己管理类似 2D 的访问时:
int row=100;
int col=100;
char* buffer = malloc(sizeof(char)*row*col);
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
buffer[i*col+j]=128;
}
}
这会比创建 'conventional' 二维数组时(显着)快吗,因为在前者中我通过顺序访问实现了缓冲区优化?还是我想错了?
int row=100;
int col=100;
char buffer[row][col];
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
buffer[i][j]=128;
}
}
感谢您的解释。
抛开动态内存分配的(小)开销,如果您通过 [row][column]
或 * (row * rowsize + column)
访问内存区域中的特定元素,则没有区别。基本上只是符号上的不同。
所以你的问题更像是"is it better to have arrays defined "排在第一位”而不是"column first?"。
答案是:只有您自己知道,因为您是根据应用程序的需要定义内存区域访问模式的人。
我不会考虑太多,除非你处理非常大的数组(其中一维大于适合你的缓存的维度)。
注1:
在第一个代码片段中,数组分配在进程的堆上,而在第二个代码片段中,您在堆栈上分配缓冲区。如果你想使用更大的数组,你可能会得到一个...... Whosebug :)
注2:
我的解释侧重于您想要动态分配二维数组的情况,使用类型**(在您的情况下为 int**)。
处理二维数组时,将其分配为一维数组并使用智能索引将其作为二维数组进行访问会更快。这是因为:
- 一维数组在内存中填充一个连续的 space(较低的碎片)。这样可以更好地缓存数组,减少访问延迟。
- 分配二维数组时,您有另一层间接,这意味着您需要先获取行的地址,然后再访问元素。当您使用一维数组时,您可以直接访问元素。
- 当数组以一维方式分配时,很容易将其与缓存行大小对齐。这将使编译器更容易优化事务并避免必须对落在缓存行边界上的元素进行 2 次读取。
- 处理一维数组,应该有助于编译器生成更好的向量化代码。
刚刚偶然发现了这个最近的问题:
How can I have a dynamically allocated 2D array in C?
我只是想知道:当我用一个简单的 malloc 创建一个 2D 数组并像这样自己管理类似 2D 的访问时:
int row=100;
int col=100;
char* buffer = malloc(sizeof(char)*row*col);
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
buffer[i*col+j]=128;
}
}
这会比创建 'conventional' 二维数组时(显着)快吗,因为在前者中我通过顺序访问实现了缓冲区优化?还是我想错了?
int row=100;
int col=100;
char buffer[row][col];
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
buffer[i][j]=128;
}
}
感谢您的解释。
抛开动态内存分配的(小)开销,如果您通过 [row][column]
或 * (row * rowsize + column)
访问内存区域中的特定元素,则没有区别。基本上只是符号上的不同。
所以你的问题更像是"is it better to have arrays defined "排在第一位”而不是"column first?"。
答案是:只有您自己知道,因为您是根据应用程序的需要定义内存区域访问模式的人。
我不会考虑太多,除非你处理非常大的数组(其中一维大于适合你的缓存的维度)。
注1:
在第一个代码片段中,数组分配在进程的堆上,而在第二个代码片段中,您在堆栈上分配缓冲区。如果你想使用更大的数组,你可能会得到一个...... Whosebug :)
注2:
我的解释侧重于您想要动态分配二维数组的情况,使用类型**(在您的情况下为 int**)。
处理二维数组时,将其分配为一维数组并使用智能索引将其作为二维数组进行访问会更快。这是因为:
- 一维数组在内存中填充一个连续的 space(较低的碎片)。这样可以更好地缓存数组,减少访问延迟。
- 分配二维数组时,您有另一层间接,这意味着您需要先获取行的地址,然后再访问元素。当您使用一维数组时,您可以直接访问元素。
- 当数组以一维方式分配时,很容易将其与缓存行大小对齐。这将使编译器更容易优化事务并避免必须对落在缓存行边界上的元素进行 2 次读取。
- 处理一维数组,应该有助于编译器生成更好的向量化代码。