Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.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++_Inline_Simd_Clang++_Auto Vectorization - Fatal编程技术网

C++ 为什么内联函数中的循环不能正确地自动矢量化?

C++ 为什么内联函数中的循环不能正确地自动矢量化?,c++,inline,simd,clang++,auto-vectorization,C++,Inline,Simd,Clang++,Auto Vectorization,我正在尝试将一些简单的计算矢量化,以提高SIMD体系结构的速度。然而,我还想把它们作为内联函数,因为函数调用和非矢量化代码也需要计算时间。然而,我不能总是同时实现这些目标。事实上,我的大多数内联函数都无法自动矢量化。下面是一个简单的测试代码: inline void add1(double *v, int Length) { for(int i=0; i < Length; i++) v[i] += 1; } void call_add1(double v[], int L) {

我正在尝试将一些简单的计算矢量化,以提高SIMD体系结构的速度。然而,我还想把它们作为内联函数,因为函数调用和非矢量化代码也需要计算时间。然而,我不能总是同时实现这些目标。事实上,我的大多数内联函数都无法自动矢量化。下面是一个简单的测试代码:

inline void add1(double *v, int Length) {
    for(int i=0; i < Length; i++) v[i] += 1;
}

void call_add1(double v[], int L) {
    add1(v, L);
}

int main(){return 0;}
inline void add1(双*v,整数长度){
对于(inti=0;i
在Mac OS X 10.12.3上,编译它:

clang++ -O3 -Rpass=loop-vectorize -Rpass-analysis=loop-vectorize -std=c++11 -ffast-math test.cpp

test.cpp:2:5: remark: vectorized loop (vectorization width: 2, interleaved count: 2) [-Rpass=loop-vectorize]
    for(int i=0; i < Length; i++) v[i] += 1;
    ^
clang++-O3-Rpass=loop vectorize-Rpass analysis=loop vectorize-std=c++11-ffast math test.cpp
测试cpp:2:5:备注:向量化循环(向量化宽度:2,交错计数:2)[-Rpass=循环向量化]
对于(inti=0;i
但是,类似的情况(仅在call_add1中移动参数)不起作用:

inline void add1(double *v, int Length) {
    for(int i=0; i < Length; i++) v[i] += 1;
}

void call_add1() {
    double v[20]={0,1,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9}; 
    int L=20;
    add1(v, L);
}

int main(){ return 0;}
inline void add1(双*v,整数长度){
对于(inti=0;i

使用同一命令编译不会产生任何输出。为什么会发生这种情况?如何确保内联函数中的循环始终自动矢量化?我想对许多函数循环进行矢量化,所以我希望修复不会太复杂。

这是因为对于第二种情况,编译器知道没有副作用,并且使用
-O3
优化了clang 4.0.0中的所有内容,只剩下:

call_add1():
  rep ret
main:
  xor eax, eax
  ret
而且你没有得到关于回路魔术的营销

在第一种情况下,编译器确实为函数生成了一些主体,因为函数确实修改了参数。如果您将其编译为对象文件。你可以链接到这个函数,它就可以工作了。我猜如果参数是const,那么函数也可能是空的


当您打印出内容时,程序并不完全相同,但它们都使用矢量化指令:

当明确指定
v
时,编译器似乎只需展开并优化循环。这是一件好事:不需要执行的代码是最快的


要验证这是一个优化,您可以尝试使一些变量变为volatile()。

使用
-fsave optimization record
编译代码表明循环已展开,然后被消除

--- !Passed
Pass:            loop-unroll
Name:            FullyUnrolled
DebugLoc:        { File: main.cpp, Line: 2, Column: 5 }
Function:        _Z9call_add1v
Args:            
  - String:          'completely unrolled loop with '
  - UnrollCount:     '20'
  - String:          ' iterations'
...
--- !Passed
Pass:            gvn
Name:            LoadElim
DebugLoc:        { File: main.cpp, Line: 2, Column: 40 }
Function:        _Z9call_add1v
Args:            
  - String:          'load of type '
  - Type:            double
  - String:          ' eliminated'
  - String:          ' in favor of '
  - InfavorOfValue:  '0.000000e+00'

如果您将4000个元素放入数组,它将超过优化器阈值,并且clang将启用矢量化。

我不确定,但我认为某些常量的正确性可能会在这里发挥很大作用……请看编译器生成的汇编代码。可以优化整个函数,也可以在编译时计算结果。另外,在第二种情况下,编译器知道数组不够大,无法进行矢量化。只是猜测。这是相当多的C代码,不是C++。@ Alxf谢谢你的回答!我不能理解汇编代码。我试图将当前时间添加到向量中,但仍然不起作用。对于(int i=0;iAgain,编译时已知大小的小数组。有些离题-如果您对低级优化感兴趣,您需要至少了解一点汇编。所有此类问题的真正答案都在那里。哈哈。有用的开关!