C 为什么在for循环中引用全局变量要慢得多?

C 为什么在for循环中引用全局变量要慢得多?,c,C,我在读一本书,书中说使用局部变量来消除不必要的内存引用。例如,下面的代码不是很有效: int gsum; //global sum variable void foo(int num) { for (int i = 0; i < num; i++) { gsum += i; } } intgsum//全局和变量 void foo(int num){ for(int i=0;i

我在读一本书,书中说使用局部变量来消除不必要的内存引用。例如,下面的代码不是很有效:

int gsum;  //global sum variable
void foo(int num) {
    for (int i = 0; i < num; i++) {
       gsum += i;
    }
}
intgsum//全局和变量
void foo(int num){
for(int i=0;i
使用以下代码更有效:

void foo(int num) {
    int fsum;
    for (int i = 0; i < num; i++) {
       fsum += i;
    }
    gsum = fsum;
}
void foo(int num){
int fsum;
for(int i=0;i
我知道第二种情况使用了存储在寄存器中的局部变量。这就是为什么它要快一点,而在第一种情况下,
gsum
必须从主内存中检索太多次

但我仍有疑问:

Q1-gcc编译器是否足够聪明,能够检测到它并隐式地使用寄存器来存储全局变量,以便后续引用将使用与第二种情况完全相同的寄存器


如果出于某种原因,编译器无法优化,那么我们仍然拥有缓存。从缓存中引用全局变量仍然非常快,但我发现一些使用局部变量的程序比引用全局变量的程序快10倍。为什么会这样?

Q1:在后续调用
foo
之间调用的其他函数可能需要该寄存器。这意味着无论何时调用此函数,
gsum
都需要在寄存器中来回穿梭


问题2:包含
gsum
的页面可能会在缓存中保留一段时间。但是,根据您的计算机正在执行的其他操作,该页可能会被写入以交换空间,以便在内存中为其他页腾出空间。

签出。生成的代码本质上是
if(num>0)gsum+=num*num完全没有循环。请注意,如果
num
为负值,则行为是未定义的,因为必须发生整数溢出,因此编译器在这种情况下可以随心所欲(在这里,什么都不做)原因我不明白。叮当声不会那么做。可能只是遗漏了一个优化(或者可能是未遗漏的悲观),但将其更改为不容易用封闭形式表示的形式,您将看到编译器完全按照您的建议执行。在整个循环中,值都保存在寄存器中,并且只在循环结束时存储回。更棘手的情况是,如果在循环中调用(非内联)函数。编译器无法知道函数是否访问全局变量,因此必须在每次函数调用时存储并重新加载它。如果您知道这不会发生,那么使用局部变量可能会有所帮助。第二个版本使用未初始化的
fsum
,将其设置为o
0
gsum
全局变量保证为0,而局部变量则不是。