使用指针和双指针访问时的性能差异

Chi*_*nna 5 c memory performance memory-access

  1. 使用指针和双指针访问内存位置时是否存在性能差异?
  2. 如果是这样,哪一个更快?

ami*_*mit 7

没有简单的答案,因为答案可能取决于实际的机器.如果我没记错的话,一些传统机器(例如PDP11)在单个指令中提供了"双指针"访问.

但是,今天情况并非如此.访问内存并不像它看起来那么简单,并且由于虚拟内存需要大量工作.出于这个原因 - 我的猜测是,在大多数现代机器上,双引用实际上应该更慢 - 需要做更多的工作才能将两个地址从虚拟地址转换为物理地址并检索它们 - 但这只是受过教育的猜测.
但请注意,编译器可能已经为您优化了"冗余"访问.

然而,据我所知,没有机器具有比"单一访问"更快的"双重访问",因此我们可以说单一访问并不比双访问更糟糕.

作为旁注,我相信现实生活中的程序,差异是可以忽略的(与程序中的其他任何东西相比),除非在一个性能敏感的循环中完成 - 只要做一些更具可读性的东西.此外,如果可以,编译器可能已经为您优化了它.


Jim*_*mbo 5

假设你在谈论类似的东西

int a = 10;
int *aptr = &a;
int **aptrptr = &aptr;
Run Code Online (Sandbox Code Playgroud)

然后费用

*aptr = 20;
Run Code Online (Sandbox Code Playgroud)

是一个解除引用.aptr必须首先检索指向的地址,然后将地址存储到.

的代价

**aptrptr = 30;
Run Code Online (Sandbox Code Playgroud)

有两个解除引用.aptrptr必须首先检索指向的地址.然后必须检索存储在该地址中的地址.然后可以存储此地址.

这是你问的吗?

因此,如果符合您的需要,使用单个指针结束会更快.

请注意,如果您在循环中访问指针或双指针,例如,

while(some condition)
    *aptr = something;
Run Code Online (Sandbox Code Playgroud)

要么

while(some condition)
    **aptrptr = something;
Run Code Online (Sandbox Code Playgroud)

编译器可能会进行优化,以便在循环开始时只进行一次解除引用,因此成本只有1个额外的地址提取而不是N,其中N是循环执行次数的numnber.

编辑:(1)正如Amit正确地指出指针访问的"如何"不是显式的C事物......它确实依赖于底层架构.如果您的机器支持双重取消引用作为单个指令,那么可能没有太大的区别.他是用的递延寻址模式索引中的PDP11作为一个例子.您可能会发现这样的指令仍然会占用更多周期...请参阅硬件文档并查看C编译器能够应用于特定体系结构的优化.

PDP11架构是大约20世纪70年代.据我所知(如果有人知道现代架构可以做这个请求!),大多数RISC架构并没有这样的双重引用,据我所知,可能需要做两次读取.

因此,使用单个指针得出的结论通常可能更快,但需要注意的是,特定架构可能比其他架构更好地处理这个问题,并且正如我所讨论的那样,编译器优化可能会使差异可以忽略不计......确保您只需要配置文件你的代码并阅读你的架构:)