【问题标题】:How to accelerate pointer dereferencing?如何加速指针解引用?
【发布时间】:2018-02-04 13:12:00
【问题描述】:

这是我的代码:

#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;
}

此代码使用仅在执行时才知道的值填充选项卡

在这种情况下没有太大问题,因为 lineSize、columnSize 和 cellSize 都很小,问题是当 cellSize 变为 100000+ 时,取消引用指针在时间上会变得很昂贵, 这就是为什么我想使用指针来避免取消引用。

问题是我不知道该怎么做才能让指针随着行、列或单元格的变化而更新。

感谢您的帮助,谢谢。

编辑:更多解释:


lineSize、columnSize 和 cellSize 越大,执行的时间越长。这是意料之中的,但需要“大量时间”的是循环内部的内容,而循环内部是一个取消引用 16*16*100000 次的指针 (When cellSize = 100000)。

如果我是对的,取消引用是一个乘法,例如:

tab[2][5][3] = tab + 2*16*100000 + 5*100000 + 3;

像这样计算 16*16*100000 次很长。

所以为了避免数学问题,我想到了一个永久指向tab[line][column][cell] 的指针,但我不知道该怎么做,而不必在每次增加 cell 时重新计算指针。

【问题讨论】:

  • 为什么不将地址的确定(即写入指针变量)移到循环中?如果您通过该指针访问多次,则可以节省时间。如果你不是,那么引入指针是朝错误方向迈出的一步。只需直接访问tab[line][column][cell],一次或两次。
  • @Yunnosch 将指针地址的确定直接移入循环将无济于事。它将执行与我仅使用 tab[line][column][cell] 完全相同的计算量
  • 这仅适用于单次访问。实际上,首先存储指针的成本更高。正如我所说,这是朝着错误方向迈出的一步。
  • 您可以采取冒险的方式,即通过差异增加指针(根据您的适当数学)。但是,有龙。
  • @Yunnosch 我会测试一下

标签: c pointers dereference


【解决方案1】:

对于 3-D 数组,您不能将指针移动到除最后一维之外的新位置。您可以沿cell 维度移动ptr,但不能沿其他维度移动。

为此,只需添加距离:

ptr2 = ptr + dist

您在编辑中提到的计算与取消引用不同,它们在您将 1-D 数组解释为 3-D 数组时使用。这将允许沿所有维度移动。


您可以执行以下操作:

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];

【讨论】:

    【解决方案2】:

    您的代码中有 UB。

    tab[line][column][cell]; 
    

    不适用于单独的 malloc 值。它仅适用于数组,这些数组是容纳所有表元素的连续内存块。您的块可能在内存中的任何位置。

    【讨论】:

    • 这不是tab[line][column][cell] 不起作用,而是您不能在“顶部”执行此操作,然后将指针向前移动,就像它是一个连续的块一样。 (虽然不是我的反对意见,我明白你在说什么,但我认为第一句话可能会让人们感到困惑)
    猜你喜欢
    • 2011-04-28
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-06
    相关资源
    最近更新 更多