首页 > 解决方案 > 全局变量在 C 中的紧密循环内读取

问题描述

假设我在 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]*cvs.的a[i]*c_cp问题吗?

我自己的研究

标签: cperformancestackglobal-variablesglobal

解决方案


任何相当聪明的编译器都会优化您的代码,使其表现得像您的第二个代码片段。使用static不会有太大变化,但如果你想确保每次迭代都读取,那么使用volatile.

关于来自不同线程的更改的要点。就单线程执行而言,编译器将保持代码的完整性。这意味着它可以重新排序您的代码、跳过某些内容、添加一些内容——只要最终结果仍然相同。

对于多个线程,您的工作是确保事情仍然以特定的顺序发生,而不仅仅是最终结果是正确的。确保是内存屏障的方法。这是一个有趣的话题,但除非你是专家,否则最好避免。


推荐阅读