【发布时间】:2020-11-15 11:48:00
【问题描述】:
假设我在 C 中有一个紧密循环,在其中我使用全局变量的值来进行一些算术运算,例如
double c;
// ... initialize c somehow ...
double f(double*a, int n) {
double sum = 0.0;
int i;
for (i = 0; i < n; i++) {
sum += a[i]*c;
}
return sum;
}
使用c 全局变量。 c 在每次循环迭代中是否“从全局范围重新读取”?毕竟,它可能已经被其他一些执行其他功能的线程改变了,对吧?因此,通过在循环之前获取c 的本地(函数堆栈)副本并仅使用此副本,代码会更快吗?
double f(double*a, int n) {
double sum = 0.0;
int i;
double c_cp = c;
for (i = 0; i < n; i++) {
sum += a[i]*c_cp;
}
return sum;
}
虽然我没有指定c 是如何初始化的,但我们假设它以某种方式完成,使得在编译时该值是未知的。此外,c 在整个运行时实际上是一个常量,即我作为程序员知道它的值不会改变。我可以让编译器了解这些信息吗,例如在全局范围内使用static double c?这会改变a[i]*c 与a[i]*c_cp 的问题吗?
我自己的研究
【问题讨论】:
-
您的第一个代码可以是optimized to read
conly once。 -
@MikeCAT 这与我的问题中的神螺栓链接有何不同(显然仍然让我感到困惑)?
-
c“可以”被其他线程更改,但不应该。根据 C 2018 5.1.2.4 中的规则,允许编译器将c视为没有被其他线程更改,因此程序员有责任确保不会发生这种情况。因此,在您显示的特定代码中,编译器可能会在每个函数调用中加载一次c。但是,假设您的代码包含一个赋值,例如a[i] = …;。然后编译器无法知道a[i]是否与c相同(实际上,这只会被定义为i等于0 或可能为-1),因此它必须防止这种情况发生。
标签: c performance stack global-variables global