gpt4 book ai didi

c - GCC是否缓存循环变量?

转载 作者:行者123 更新时间:2023-12-03 17:05:59 25 4
gpt4 key购买 nike

当我有一个循环时:

for (int i = 0; i < SlowVariable; i++)
{
//
}

我知道在 VB6 中,SlowVariable 会在循环的每次迭代中被访问,从而使以下操作更加高效:

int cnt = SlowVariable;

for (int i = 0; i < cnt; i++)
{
//
}

我是否需要在 GCC 中进行相同的优化?或者它只计算一次 SlowVariable

最佳答案

这称为在循环之外“提升”SlowVariabele

只有当编译器能够证明 SlowVariabele 的值每次都相同,并且评估 SlowVariabele 没有副作用时,编译器才能做到这一点。

例如,请考虑以下代码(为了举例,我假设由于某种原因通过指针访问“很慢”):

void foo1(int *SlowVariabele, int *result) {
for (int i = 0; i < *SlowVariabele; ++i) {
--*result;
}
}

编译器不能(通常)提升,因为它知道它将被调用 result == SlowVariabele,因此 *SlowVariabele 的值正在改变在循环期间。

另一方面:

void foo2(int *result) {
int val = 12;
int *SlowVariabele = &val;
for (int i = 0; i < *SlowVariabele; ++i) {
--*result;
}
}

现在至少在原则上,编译器可以知道 val 在循环中永远不会改变,因此它可以提升。它是否真的这样做取决于优化器有多积极以及它对函数的分析有多好,但我希望任何严肃的编译器都能做到这一点。

类似地,如果 foo1 是使用编译器可以确定(在调用站点)不相等的指针调用的,并且如果调用是内联的,则编译器可以提升。这就是 restrict 的用途:

void foo3(int *restrict SlowVariabele, int *restrict result) {
for (int i = 0; i < *SlowVariabele; ++i) {
--*result;
}
}

restrict(在 C99 中引入)表示“您不得使用 result == SlowVariabele 调用此函数”,并允许编译器提升。

类似地:

void foo4(int *SlowVariabele, float *result) {
for (int i = 0; i < *SlowVariabele; ++i) {
--*result;
}
}

严格的别名规则意味着 SlowVariableresult 不能引用相同的位置(或者程序无论如何都有未定义的行为),因此编译器可以再次提升.

关于c - GCC是否缓存循环变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14625888/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com