在C++中,当一个数组的元素在一个循环中被多次使用时,是不是把它赋值给另一个元素更好?
In C++, when an element of an array is used multiple times in a loop, is it better to assign it to an other element?
假设我有一个循环,可以对数组 x
进行一些数学运算。在每次迭代时在循环内分配一个临时双精度数还是我应该每次都使用 array[i]
更好?
我所说的更好是指使用 C++ 在性能方面。我想知道 C++ 是否有一些我正在破坏的矢量化或现金优化?
此外,如果我使用此数组调用一个函数并且我可能多次需要一个函数的值怎么办,所以我通常对函数执行相同的操作。我认为这比多次调用该函数要好。
如果循环使用 omp parallel
,我认为这应该是安全的,对吗?
for(int i=0; i<N; i++){
double xi = X[i];
double fi = f(xi);
t[i] = xi*xi + fi + xi/fi;
}
现代编译器(最近 10 年)会优化它。不用担心。
编辑:
这已在 Whosebug 中讨论过几次:
Will compiler optimize and reuse variable
In C++, should I bother to cache variables, or let the compiler do the optimization? (Aliasing)
这个官方documentation explains吧,恕我直言吧
-fmerge-all-constants
-fivopts
也许 -ftree-coalesce-vars
clang 和 MSCV 有类似的选项,您可以自己研究它们或在这里 link 它们。
实际上,当编译器看到内存读取(变量或数组值)时,它会将其读入寄存器,除非未标记为 volatile
,编译器可以假定它没有更改,不会发出指令重新阅读。
说了神奇的volatile
一句话:不应该用于线程。它应该用于硬件映射内存(例如,视频卡内存或外部端口)。
elcuco 是正确的。任何称职的编译器都能够优化这种微不足道的东西。这里重要的是代码的可读性,我个人觉得 X[i]
在这种情况下更容易看。
我会注意到,如果您重复发表很长的陈述,即 X.something.something.darkside[i][j]
,使用明确命名的引用可能是有意义的,即 auto & the_emperor = X.something.something.darkside[i][j]
.
假设我有一个循环,可以对数组 x
进行一些数学运算。在每次迭代时在循环内分配一个临时双精度数还是我应该每次都使用 array[i]
更好?
我所说的更好是指使用 C++ 在性能方面。我想知道 C++ 是否有一些我正在破坏的矢量化或现金优化?
此外,如果我使用此数组调用一个函数并且我可能多次需要一个函数的值怎么办,所以我通常对函数执行相同的操作。我认为这比多次调用该函数要好。
如果循环使用 omp parallel
,我认为这应该是安全的,对吗?
for(int i=0; i<N; i++){
double xi = X[i];
double fi = f(xi);
t[i] = xi*xi + fi + xi/fi;
}
现代编译器(最近 10 年)会优化它。不用担心。
编辑:
这已在 Whosebug 中讨论过几次: Will compiler optimize and reuse variable In C++, should I bother to cache variables, or let the compiler do the optimization? (Aliasing)
这个官方documentation explains吧,恕我直言吧
-fmerge-all-constants
-fivopts
也许 -ftree-coalesce-vars
clang 和 MSCV 有类似的选项,您可以自己研究它们或在这里 link 它们。
实际上,当编译器看到内存读取(变量或数组值)时,它会将其读入寄存器,除非未标记为 volatile
,编译器可以假定它没有更改,不会发出指令重新阅读。
说了神奇的volatile
一句话:不应该用于线程。它应该用于硬件映射内存(例如,视频卡内存或外部端口)。
elcuco 是正确的。任何称职的编译器都能够优化这种微不足道的东西。这里重要的是代码的可读性,我个人觉得 X[i]
在这种情况下更容易看。
我会注意到,如果您重复发表很长的陈述,即 X.something.something.darkside[i][j]
,使用明确命名的引用可能是有意义的,即 auto & the_emperor = X.something.something.darkside[i][j]
.