间接指针对效率的影响有多大?

How much does pointer indirection affect efficiency?

本文关键字:影响 指针 效率      更新时间:2023-10-16

解引用指针是否明显比直接访问该值慢?我想我的问题是,偏差算子有多快?

由于现代CPU的工作方式,间接遍历指针可能要慢得多。但它与运行时内存没有太大关系。

相反,速度受到预测和缓存的影响。

预测很容易,当指针没有被改变或以可预测的方式改变时(例如,在循环中增加或减少4)。这允许CPU在实际代码执行之前运行,计算出指针的值,并将该地址加载到缓存中。当指针值由一个复杂的表达式(如哈希函数)构建时,预测变得不可能。

缓存起作用是因为指针可能指向不在缓存中的内存,并且必须提取它。如果预测工作,这是最小化的,但如果预测是不可能的,那么在最坏的情况下,你可以有双重影响:指针不在缓存中,指针目标也不在缓存中。在最坏的情况下,CPU会停止两次。

如果该指针用于函数指针,则CPU的分支预测器开始发挥作用。在c++虚表中,函数值都是常量,预测器很容易做到。当执行通过间接跳转时,CPU将使代码准备好运行并处于管道中。但是,如果它是一个不可预测的函数指针,则性能影响可能很大,因为管道需要刷新,每次跳转都会浪费20-40个CPU周期。

取决于以下内容:

  • "直接访问"的值是否已经在寄存器中,或者在堆栈中(这也是一个间接的指针)
  • 目标地址是否已经在缓存中
  • 缓存体系结构,总线体系结构等

也就是说,没有缩小范围,太多的变量无法有效地推测。

如果您真的想知道,可以在您的特定硬件上进行基准测试。

需要更多的内存访问:

  1. 读取存储在指针变量
  2. 中的地址
  3. 读取地址
  4. 处的值

这不能等于2个简单的操作,因为它可能需要更多的时间,因为访问尚未加载在缓存中的地址。

假设您正在处理一个真正的指针(不是某种智能指针),解引用操作根本不消耗(数据)内存。但它确实(潜在地)涉及到一个额外的内存引用:一个用于加载指针本身,另一个用于访问指针所指向的数据。

如果你在紧循环中使用指针,它通常会在持续时间内被加载到寄存器中。在这种情况下,代价主要是额外的寄存器压力(即,如果您使用寄存器来存储指针,则不能同时使用它来存储其他内容)。如果您有一个算法,否则将完全填充寄存器,但注册指针将溢出内存,这可以产生不同。曾经,这是一个相当大的损失,但是对于大多数现代cpu(具有更多的寄存器和板载缓存),这很少是一个大问题。一个明显的例外将是具有更少寄存器和没有缓存(并且没有片上内存)的嵌入式CPU。

最重要的是,它通常是可以忽略不计的,通常低于你甚至可以可靠地测量它的阈值。

是的。这需要额外收费。
按值访问变量,直接从其内存位置读取变量。
通过指针访问相同的变量会增加从指针获取变量的地址,然后从该内存位置读取值的开销。

当然,假设变量没有被放置在寄存器中,在某些情况下,比如紧循环。我相信这个问题是在假设没有这种情况的情况下寻求开销的答案。