如何加速指针取消引用?
How to accelerate pointer dereferencing?
这是我的代码:
#include <stdlib.h> //malloc
#define lineSize 16
#define columnSize 16
#define cellSize 16
int main()
{
unsigned char*** tab;
tab = malloc(sizeof(unsigned char**) * lineSize);
for(unsigned int i = 0; i < lineSize; i++)
tab[i] = malloc(sizeof(unsigned char*) * columnSize);
for(unsigned int i = 0; i < lineSize; i++)
for(unsigned int j = 0; j < columnSize; j++)
tab[i][j] = malloc(sizeof(unsigned char) * cellSize);
unsigned int line = 0;
unsigned int column = 0;
unsigned int cell = 0;
unsigned char* ptr = &tab[line][column][cell];
for(line = 0; line < lineSize; line++)
for(column = 0; column < columnSize; column++)
for(cell = 0; cell < cellSize; cell++)
*ptr = ...;
return 0;
}
This code fills tab with values that are only known at execution time
在这种情况下,没有太多问题,因为 lineSize、columnSize 和 cellSize 很小,问题是当 cellSize 变为 100000+ 时,取消引用指针在时间上变得昂贵,
这就是为什么我想使用指针来避免取消引用。
问题是我不知道如何才能让指针随着行、列或单元格的变化而更新。
感谢您的帮助,谢谢。
编辑:更多解释:
lineSize、columnSize、cellSize越大,执行时间越长。这是预料之中的,但是需要 "lot of time" 的是循环内部的内容,而循环内部是一个指针取消引用 16*16*100000 次 (When cellSize = 100000
).
If I'm right, Dereferencing is a multiplication like:
tab[2][5][3] = tab + 2*16*100000 + 5*100000 + 3;
然后像那样做数学运算 16*16*100000 次就很长了。
所以为了避免数学运算,我想到了一个永久指向 tab[line][column][cell]
的指针,但我不知道如何做到这一点,而不必在每次递增 cell
时都重新计算指针。
对于 3 维数组,除了最后一个维度之外,您不能将指针移动到新位置。您可以沿 cell
维度移动 ptr
,但不能沿其他维度移动。
为此,只需添加距离:
ptr2 = ptr + dist
您在编辑中提到的计算与解引用不同,当您将一维数组解释为三维数组时会使用它们。这将允许沿所有维度移动。
您可以执行以下操作:
for(line = 0; line < lineSize; line++) {
unsigned char** my_line = tab[line];
for(column = 0; column < columnSize; column++)
unsigned char* my_col = my_line[column];
for(cell = 0; cell < cellSize; cell++)
unsigned char data = my_col[cell];
您的代码中有 UB。
tab[line][column][cell];
不适用于单独分配的值。它仅适用于数组,这些数组是容纳所有 table 元素的连续内存块。您的块可能在内存中的任何位置。
这是我的代码:
#include <stdlib.h> //malloc
#define lineSize 16
#define columnSize 16
#define cellSize 16
int main()
{
unsigned char*** tab;
tab = malloc(sizeof(unsigned char**) * lineSize);
for(unsigned int i = 0; i < lineSize; i++)
tab[i] = malloc(sizeof(unsigned char*) * columnSize);
for(unsigned int i = 0; i < lineSize; i++)
for(unsigned int j = 0; j < columnSize; j++)
tab[i][j] = malloc(sizeof(unsigned char) * cellSize);
unsigned int line = 0;
unsigned int column = 0;
unsigned int cell = 0;
unsigned char* ptr = &tab[line][column][cell];
for(line = 0; line < lineSize; line++)
for(column = 0; column < columnSize; column++)
for(cell = 0; cell < cellSize; cell++)
*ptr = ...;
return 0;
}
This code fills tab with values that are only known at execution time
在这种情况下,没有太多问题,因为 lineSize、columnSize 和 cellSize 很小,问题是当 cellSize 变为 100000+ 时,取消引用指针在时间上变得昂贵, 这就是为什么我想使用指针来避免取消引用。
问题是我不知道如何才能让指针随着行、列或单元格的变化而更新。
感谢您的帮助,谢谢。
编辑:更多解释:
lineSize、columnSize、cellSize越大,执行时间越长。这是预料之中的,但是需要 "lot of time" 的是循环内部的内容,而循环内部是一个指针取消引用 16*16*100000 次 (When cellSize = 100000
).
If I'm right, Dereferencing is a multiplication like:
tab[2][5][3] = tab + 2*16*100000 + 5*100000 + 3;
然后像那样做数学运算 16*16*100000 次就很长了。
所以为了避免数学运算,我想到了一个永久指向 tab[line][column][cell]
的指针,但我不知道如何做到这一点,而不必在每次递增 cell
时都重新计算指针。
对于 3 维数组,除了最后一个维度之外,您不能将指针移动到新位置。您可以沿 cell
维度移动 ptr
,但不能沿其他维度移动。
为此,只需添加距离:
ptr2 = ptr + dist
您在编辑中提到的计算与解引用不同,当您将一维数组解释为三维数组时会使用它们。这将允许沿所有维度移动。
您可以执行以下操作:
for(line = 0; line < lineSize; line++) {
unsigned char** my_line = tab[line];
for(column = 0; column < columnSize; column++)
unsigned char* my_col = my_line[column];
for(cell = 0; cell < cellSize; cell++)
unsigned char data = my_col[cell];
您的代码中有 UB。
tab[line][column][cell];
不适用于单独分配的值。它仅适用于数组,这些数组是容纳所有 table 元素的连续内存块。您的块可能在内存中的任何位置。