Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.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++ 我对元素级sqrt的SSE/AVX优化没有提升,为什么_C++_Optimization_Sse_Simd - Fatal编程技术网

C++ 我对元素级sqrt的SSE/AVX优化没有提升,为什么

C++ 我对元素级sqrt的SSE/AVX优化没有提升,为什么,c++,optimization,sse,simd,C++,Optimization,Sse,Simd,我是SIMD优化的新手,尝试为1D浮点数组计算每个元素的sqrt值 系统:视窗10 编译器:Visual Studio 2017 CPU:Intel Core i5-8500 下面的代码是在发布模式下编译和运行的,但是正常(原始)实现的速度几乎与SSE和AVX优化版本的速度相同。不知道为什么。我的实现或我做性能测试的方法是错误的吗 #包括 #包括 #包括 #包括 #包括,我们可以看到: /O1 (Minimize Size) /Og /Os /Oy /Ob2 /GF /Gy /O2 (Maxim

我是SIMD优化的新手,尝试为1D浮点数组计算每个元素的sqrt值

系统:视窗10 编译器:Visual Studio 2017 CPU:Intel Core i5-8500

下面的代码是在发布模式下编译和运行的,但是正常(原始)实现的速度几乎与SSE和AVX优化版本的速度相同。不知道为什么。我的实现或我做性能测试的方法是错误的吗

#包括
#包括
#包括
#包括
#包括,我们可以看到:

/O1 (Minimize Size) /Og /Os /Oy /Ob2 /GF /Gy
/O2 (Maximize Speed)    /Og /Oi /Ot /Oy /Ob2 /GF /Gy

我看到的第一件事是,您正在使用服务器内存副本。您可以通过定义联合来忽略这些因素:

union f64_m256{
double f[4];
__m256d m; 
} 
现在,f64_m256类型的每个对象都占用相同的内存位置(这些类型共享相同的256位)。 您现在可以执行以下操作,例如:

//build x as a combined type - builds first the array
f64_m256 x = {1.,2.,3.,4.}; 

//calculate the sqrt via simd and return it to x 
x.m = _mm256_sqrt_pd(x.m);

//access the calculated sqrts
cout << x.f[2] << endl;
//将x构建为组合类型-首先构建数组
f64_m256 x={1,2,3,4};
//通过simd计算sqrt并将其返回给x
x、 m=毫米256平方米(x.m);
//访问计算的SQRT

cout看来您的第一个循环已经优化了。我通过添加带有随机索引的cout语句来强制保留它

典型结果:

normal: 9.203 ms
sse:    0.814 ms
avx:    0.678 ms

有趣的是,即使启用了自动矢量化,正常的
时间也没有改善。

编译器是否自动矢量化了标量版本<代码>a[i]=sqrt(a[i])应该可以使用现代编译器轻松地进行矢量化。使用
gcc-O3-fno-tree-vectorize
或MSVC的任何等效工具进行尝试。可能会优化尺寸而不是速度?(MSVC是否调用
-O1
?)@PeterCordes我使用的是/O2,默认情况下由cmake提供。切换到/O1会使
normal
变慢。是的,通常情况下,您应该进行全面优化,以便编译器在知道如何生成代码时能够快速生成代码。这表明手动矢量化这个循环并没有什么好处。在MSVC 2019中,O1和O2导致相同的性能。第一个版本自动矢量化为
sqrtps
,并与SSE版本相同。顺便说一句,你看过MSVC 2019中的
\u aligned\u malloc
\u aligned\u free
?@rustyx I测试,/O1和/O2结果不同。我看到一些教程提到了你的粘贴编码风格。这有助于理解,但不会消除数据拷贝。请看我粘贴的代码,sse/avx实现,向这些函数传递一个指针,并使用类型转换,其中没有数据副本。我在main()中复制数据的目的是使用完全相同的输入数据保留3个实现。改进测试程序中没有计时的部分有什么意义?
union f64_m256{
double f[4];
__m256d m; 
} 
//build x as a combined type - builds first the array
f64_m256 x = {1.,2.,3.,4.}; 

//calculate the sqrt via simd and return it to x 
x.m = _mm256_sqrt_pd(x.m);

//access the calculated sqrts
cout << x.f[2] << endl;
normal: 9.203 ms
sse:    0.814 ms
avx:    0.678 ms