解除引用指针的速度要比直接访问该值慢吗?我想我的问题是 - deference运算符有多快?
答案 0 :(得分:20)
由于现代CPU的工作原理,通过指针间接可以慢得多。但它与运行时内存没什么关系。
相反,速度会受到预测和缓存的影响。
当指针未被更改或以可预测的方式更改时(例如,在循环中递增或递减4),预测很容易。这允许CPU基本上在实际代码执行之前运行,找出指针值将是什么,并将该地址加载到缓存中。当指针值由像哈希函数这样的复杂表达式构建时,预测变得不可能。
缓存起作用,因为指针可能指向不在缓存中的内存,并且必须获取它。如果预测有效,则最小化,但如果预测不可能,那么在最坏的情况下,您可能会产生双重影响:指针不在缓存中,指针目标也不在缓存中。在最糟糕的情况下,CPU会停止两次。
如果指针用于函数指针,则CPU的分支预测器开始起作用。在C ++虚拟表中,函数值都是常量,预测器很容易。当执行通过间接跳转时,CPU将准备好运行代码并在管道中运行。但是,如果它是一个不可预测的函数指针,性能影响可能会很大,因为需要刷新管道,每次跳转都会浪费20-40个CPU周期。
答案 1 :(得分:3)
取决于:
即,有太多的变量可以在不缩小范围的情况下进行有用的推测。
如果您真的想知道,请在特定硬件上进行基准测试。
答案 2 :(得分:2)
它需要更多的内存访问:
这不能等于2个简单操作,因为访问缓存中尚未加载的地址可能还需要更多时间。
答案 3 :(得分:2)
确实如此。这需要额外的取件 通过值访问变量,直接从其存储位置读取变量 通过指针访问相同的内容会增加从指针获取变量地址然后从该内存位置读取值的开销。
当然,假设变量没有放在寄存器中,在某些情况下就像紧密循环一样。我相信该问题在没有这种情况的情况下寻求开销的答案。
答案 4 :(得分:2)
假设你正在处理一个真正的指针(不是某种类型的智能指针),取消引用操作根本就不消耗(数据)内存。它确实(可能)涉及额外的内存引用:一个用于加载指针本身,另一个用于访问指针指向的数据。
但是,如果您在紧密循环中使用指针,则通常会在一段时间内将其加载到寄存器中。在这种情况下,成本主要是额外的寄存器压力(即,如果您使用寄存器来存储该指针,则不能使用它来同时存储其他内容)。如果你有一个算法,否则完全填充寄存器,但注册指针会溢出到内存,它可以有所作为。有一段时间,这是一个相当大的损失,但对于大多数现代CPU(具有更多寄存器和板载缓存),这很少是一个大问题。显而易见的例外是嵌入式CPU,寄存器更少,没有缓存(没有片上存储器)。
最重要的是,它通常可以忽略不计,通常低于您甚至可以可靠地测量它的阈值。