向指针添加"const"可以帮助优化吗?

Can adding 'const' to a pointer help the optimization?

本文关键字:优化 帮助 指针 添加 const      更新时间:2023-10-16

我有一个指针int* p,并在循环中执行一些操作。我不修改记忆,只是阅读。如果我将const添加到指针(两种情况都是const int* pint* const p),它能帮助编译器优化代码吗?

我知道const的其他优点,比如安全性或自我文档,我询问了这个特定的案例。重新表述这个问题:const能为编译器提供任何有用的(用于优化的)信息吗?

虽然这显然是特定于实现的,但很难看出将指针从int*更改为int const*会提供编译器不知道的任何附加信息。

在这两种情况下,指向的值都可能在循环执行期间发生变化。

因此,它可能不会帮助编译器优化代码。

否。使用这样的const不会为编译器提供任何可用于优化的信息。

从理论上讲,为了对编译器有所帮助,优化器必须能够证明没有人会在const指针上使用const_cast,但却无法证明变量从未被写入。这种情况极不可能发生。

赫伯·萨特在他的一个"本周大师"专栏中对此进行了更深入的报道。

它可以有所帮助,也可以没有什么不同,也可以让情况变得更糟。要知道这一点,唯一的方法是尝试两者并检查发出的机器代码。

现代编译器非常聪明,因此它们经常可以推断出内存在没有任何限定符的情况下是不变的(pr如果没有以更容易分析的方式编写代码,它们可以推断出许多其他优化是可能的),但它们相当复杂,因此有很多不足,通常不能在每一个机会都优化每一件可能的事情。

我认为编译器在您的场景中不能做太多工作。事实上,您的指针声明为const int * const p并不能保证内存不能从外部更改,例如由另一个线程更改。因此,编译器必须生成在循环的每次迭代中读取内存值的代码。

但是,如果不打算写入内存位置,并且知道没有其他代码会写入,那么您可以创建一个局部变量并使用类似的方法:

const int * p = ...
...
int val = *p;
/* use the value in a loop */
for (i = 0; i < BAZILLION; i++)
{
    use_value(val);
}

您不仅可以帮助代码的潜在读者了解val在循环中没有更改,而且还为编译器提供了优化的可能性(例如,在寄存器中加载val)。

正如其他人所说,使用const不太可能帮助编译器优化循环。

然而,它可能有助于优化循环外的代码,或者在调用const限定方法的位置,或者在使用const参数的函数的位置。

这可能取决于编译器是否能够证明它可以消除冗余负载,移动它们,或者缓存计算值,而不是重新计算它们。

证明这一点的唯一方法仍然是评测和/或检查程序集,但这可能是您应该关注的地方。

您没有说明您使用的是哪种编译器。但如果你同时在读和写记忆,你可以从使用"限制"或类似的词中受益。编译器不知道指针是否在同一内存中混叠,因此任何存储区都会强制再次加载其他值。"restrict"告诉编译器指针没有发生混叠,并且可以继续使用在后续写入之前加载的值。避免混叠问题的另一种方法是将值加载到局部变量中,这样编译器在写入后就不会被迫重新加载。