Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C可变分配时间和空间_C_Variables_Stack_Heap_Allocation - Fatal编程技术网

C可变分配时间和空间

C可变分配时间和空间,c,variables,stack,heap,allocation,C,Variables,Stack,Heap,Allocation,如果我有一个包含以下内容的test.c文件 #include ... int global = 0; int main() { int local1 = 0; while(1) { int local2 = 0; // Do some operation with one of them } return 0; } 因此,如果我必须在while循环中使用其中一个变量,那么哪一个是首选的 也许我在这里有点含糊不清,但我想知道时间/空间分配的差异是否真的相关。如果您想知道性

如果我有一个包含以下内容的test.c文件

#include ...
int global = 0;

 int main() {
 int local1 = 0;

  while(1) {
  int local2 = 0;
  // Do some operation with one of them
 }
 return 0;
}
因此,如果我必须在while循环中使用其中一个变量,那么哪一个是首选的


也许我在这里有点含糊不清,但我想知道时间/空间分配的差异是否真的相关。

如果您想知道性能差异:很可能没有。如果理论上存在性能差异,你会发现很难设计一个测试来测量它们。

这样的决定不应该基于性能,而应该基于语义。除非需要全局变量的语义行为,否则应始终使用自动(局部非静态)变量


正如其他人已经说过,也肯定会说的那样,在表现上不太可能有任何差异。如果有,自动变量会更快。

如果您想知道在for循环中声明变量是否会导致在每次迭代中创建/销毁它,那么就没有什么真正需要担心的了。这些变量不是在运行时动态分配的,这里没有任何东西被
malloc
ed,只是一些内存被预留出来在循环中使用。因此,就性能而言,将变量放在内部与将其放在循环外部是一样的


这里的真正区别在于范围而不是性能。使用全局变量还是局部变量只会影响您希望该变量可见的位置。

C编译器将更容易对声明为函数局部的变量进行优化。全局变量需要一个优化器来执行“过程间数据流分析”,这是不常见的

作为差异的一个例子,考虑所有的声明将变量初始化为零。但是,对于全局变量,编译器不能使用该信息,除非它在示例函数中使用全局变量之前验证程序中的任何控制流都不能更改全局变量。对于本地声明的(“自动”)变量,另一个函数无法更改初始值(特别是,编译器验证其地址从未传递给子函数),并且编译器可以执行“终止定义”和“值活动”分析以确定在某些代码路径中是否可以假定零值

在这两个局部变量中,作为一个指导原则,优化器总是能够更轻松地优化对范围更小(更有限)的变量的访问

如上所述,我建议其他关于偏向语义而非优化器元优化的答案是正确的。使用使代码读得最好的变量,您将获得比协助def使用优化计算更多的时间


一般来说,避免使用全局变量,或任何可访问范围比绝对必要范围更广的变量。变量的有限范围有助于防止在以后的程序维护期间引入bug。

有三大类变量:静态(全局)、堆栈(自动)和寄存器

寄存器变量存储在CPU寄存器中。寄存器是非常快的字大小的存储器,集成在CPU管道中。它们可以自由访问,但数量非常有限(通常在8到32之间,具体取决于您的处理器和正在执行的操作)

堆栈变量存储在称为堆栈的RAM区域中。堆栈几乎总是在缓存中,因此堆栈变量通常需要1-4个周期才能访问

通常,局部变量可以在寄存器中,也可以在堆栈中。不管它们是在函数顶部还是在循环中分配;每个函数调用只分配一次,分配基本上是免费的。如果可能的话,编译器会将变量放入寄存器中,但是如果活动变量多于寄存器,那么它们就不能全部匹配。此外,如果获取变量的地址,则必须将其存储在堆栈上,因为寄存器没有地址

全局变量和静态变量是不同的。因为它们通常不经常被访问,所以它们可能不在缓存中,所以访问它们可能需要数百个周期。此外,由于编译器可能无法提前知道全局变量的地址,因此可能需要查找它,这也是非常昂贵的

正如其他人所说,不要太担心这些东西。知道这一点肯定很好,但它不应该影响您编写程序的方式。编写有意义的代码,让编译器担心优化问题。如果你从事编译器开发,那么你就可以开始担心它了


编辑:有关分配的更多详细信息:

寄存器变量由编译器分配,因此没有运行时开销。一旦产生值,代码就会将值放入寄存器中


堆栈变量由程序在运行时分配。通常,调用函数时,它要做的第一件事是为其所有局部变量保留足够的堆栈空间。因此没有每个变量的成本。

这实际上取决于体系结构、编译器、编译器版本、编译器标志、月亮的相位、是否以及如何牺牲一只山羊等等。哦,我是否提到过,即使在数十亿次迭代中对循环进行计时,您也不会注意到任何差异?如果你愿意的话,去优化其他东西。如今,可变访问的性能更多地取决于它们在缓存中的存在,而不是访问它们所需的指令。经验法则:L1:3个周期,L2:15个周期,而不是缓存的150个周期。真的吗?我总是有一种“感觉”,反复声明int将需要更多的时间(仅限于