Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.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++ 在循环外声明var是坏的?_C++_Performance_Loops_Memory_Declaration - Fatal编程技术网

C++ 在循环外声明var是坏的?

C++ 在循环外声明var是坏的?,c++,performance,loops,memory,declaration,C++,Performance,Loops,Memory,Declaration,我为正在制作的DSP/音频应用程序编写了以下基本代码: double input = 0.0; for (int i = 0; i < nChannels; i++) { input = inputs[i]; 双输入=0.0; 对于(int i=0;i与原始代码相同的可观察效果。因此,在这里,假设输入变量未在循环外使用,优化编译器可以优化出行双输入=0.0;,因为在下一次赋值之前没有可观察效果:输入=输入[i]。它可以在同一个因素(循环源之外的变量分配)(无论源C++文件是否

我为正在制作的DSP/音频应用程序编写了以下基本代码:

double input = 0.0;
for (int i = 0; i < nChannels; i++) {
      input = inputs[i];
双输入=0.0;
对于(int i=0;i
一些DSP工程专家告诉我:“你不应该在循环外声明它,否则它会产生依赖,编译器无法尽可能有效地处理它。”

他说的是var
input
我想。为什么会这样?最好一次清除并覆盖它


可能与使用的不同内存位置有关?即寄存器而不是堆栈?

最好在循环中声明变量,但原因是错误的

这里有一条经验法则:在尽可能小的范围内声明变量。这样你的代码可读性更强,更不容易出错

至于性能问题,对于任何现代编译器来说,在什么地方声明变量都无关紧要。例如,
clang
从它自己的IR中完全消除了
-O1
处的变量:


然而,有一种情况是:如果您曾经使用
输入的地址,变量(很容易),并且您应该在循环内声明它,如果您关心性能的话。

最好在循环内声明变量,但原因是错误的

这里有一条经验法则:在尽可能小的范围内声明变量。这样你的代码可读性更强,更不容易出错

至于性能问题,对于任何现代编译器来说,在什么地方声明变量都无关紧要。例如,
clang
从它自己的IR中完全消除了
-O1
处的变量:


然而,有一种情况:如果您使用
输入的地址
,变量(很容易),如果你关心性能的话,你应该在循环中声明它。

80年代早期的好的旧K&R C编译器用于生成尽可能接近程序员编写的代码,程序员用于尽最大努力生成优化的源代码。现代优化编译器可以返工,只要生成的代码trong>与原始代码相同的可观察效果。因此,在这里,假设
输入
变量未在循环外使用,优化编译器可以优化出行
双输入=0.0;
,因为在下一次赋值之前没有可观察效果:
输入=输入[i]。它可以在同一个因素(循环源之外的变量分配)(无论源C++文件是否在里面),出于同样的原因。

简而言之,除非你想用一个特定的参数集为一个特定的编译器生成代码,在这种情况下,你应该彻底检查生成的汇编代码,否则你永远不要担心那些低级优化。有些人说编译器比你聪明,另一些人说编译器会以任何方式生成自己的代码死记硬背


重要的是可读性和变量范围。这里的
input
在功能上是循环本地的,所以它应该在循环内部声明。句号。任何其他优化考虑都是无用的,除非您对低级优化有特殊要求(分析显示这些行需要特殊处理)由于
input
变量未在循环外使用,优化编译器可以优化出行
double input=0.0;
,因为在下一次赋值之前没有可观察的效果:
input=inputs[i];
。并且它可以在循环外的变量赋值中使用相同的因子(源代码C++文件是否在里面),原因相同。

简而言之,除非你想用一个特定的参数集为一个特定的编译器生成代码,在这种情况下,你应该彻底检查生成的汇编代码,否则你永远不要担心那些低级优化。有些人说编译器比你聪明,另一些人说编译器会以任何方式生成自己的代码死记硬背


重要的是可读性和变量范围。这里的
input
在功能上是循环本地的,所以它应该在循环内部声明。句号。任何其他优化考虑都是无用的,除非您对低级优化有特殊要求(分析显示这些行需要特殊处理)。

许多人认为声明变量会分配一些内存供您使用。它不是这样工作的。它也不会分配寄存器

它只为您创建一个名称(和关联类型),您可以使用该名称将值的使用者与其生产者链接起来

关于一个50岁的编译器(或由学生在第三年编译器构造课程中编写的编译器),这可以通过为堆栈上的变量分配一些内存来实现,并在每次引用变量时使用这些内存。它简单、有效,而且效率极低。一个很好的进步是尽可能将局部变量放入寄存器中,但它使用寄存器的效率很低,这不是我们目前的情况(已经有一段时间了)

将使用者与生产者链接会创建一个数据流图。在大多数现代编译器中,接收寄存器的是该图中的边。在声明任何变量时,这些边都会被完全删除。它们不再存在。如果在clang中使用-emit llvm,则可以看到这一点


所以变量不是真的,它们只是标签。可以随意使用。

许多人认为声明变量会分配一些内存