2014-09-19 59 views
4

我使用SSE类型(如__m128(在xmmintrin.h等中定义))做了一些明确的向量化计算,但现在我需要将向量的所有元素都提升为一些(相同)功率,即理想情况下我想像__m128 _mm_pow_ps(__m128, float),这不幸不存在。对于SSE类型的功能

这是最好的方法是什么?我可以存储矢量,在每个元素上调用std::pow,然后重新加载它。这是我能做的最好的吗?自动矢量化代码时,编译器如何实现对std::pow的调用?有没有提供有用的东西的库?

(注意:this question是不是重复相关的,当然没有一个有用的答案。)

+0

我用http://gruntthepeon.free.fr/ ssemath/for'exp/log'并且在自动矢量化不是一个选项时写'pow(x,k)'为'exp(k * log(x)'。不知道它与自动矢量化代码的比较。 – SleuthEye 2014-09-19 14:47:23

+2

你可以使用Agner Fog的矢量类,他具有SSE,AVX和AVX512的SIMD数学函数(包括pow,exp,log,sin,...)并浮动和整数。我认为没有任何理由使用英特尔的SVML或AMD的libm了。 – 2014-09-20 15:01:02

+0

@Zboson,是否有一个很好的支持SSE4的'exp()'的C库? – Royi 2017-10-30 19:00:09

回答

7

使用公式exp(y*log(x))pow(x, y)a library用exp和日志SSE实现。

+0

为图书馆+1,先前不知道 – legends2k 2014-09-19 15:06:48

+0

我看了一下那个图书馆。它看起来仅限于gcc,只知道SSE2,代码中的文档很差。我也希望它可以用于AVX类型'__m256' __m256d'。 – Walter 2014-09-19 15:11:21

+0

@Walter可以很好地处理MSVC(注意链接底部的VS2010基准),并且在查看[cephes库](http://www.netlib.org/cephes/cmath.tgz)时代码变得更加清晰似乎是主要的灵感。 – SleuthEye 2014-09-20 00:21:01

2

我真的很推荐这些类型的操作的英特尔短矢量数学库。该库与您在要支持的编译器列表中提到的英特尔编译器捆绑在一起。我怀疑它对于gcc和clang会有用,但它可以作为您在哪里实现pow的实现进行基准测试的参考点。

https://software.intel.com/sites/products/documentation/doclib/iss/2013/compiler/cpp-lin/GUID-DEB8B19C-E7A2-432A-85E4-D5648250188E.htm

+1

SVML可以用于gcc。 'gcc -mveclibabi = svml'甚至会让矢量器创建对vmlsPow4等的调用。 – 2015-04-11 06:27:21

+0

@MarcGlisse,'gcc'包含内建的Intel SVML吗? – Royi 2017-10-30 18:30:45

+0

gcc不包含SVML,它只具有如何生成对它的调用的知识,如果你承诺你将它用于链接。 – 2017-10-30 18:33:38

-1

辨认出浮体的载体。

_mm_pow_ps(v,_mm_ps1(f)) 
+1

恐怕没有'_mm_pow_ps()'。否则,我没有问过。 – Walter 2015-04-10 11:47:19

+0

啊,我误解了这个问题。泰勒系列是传统的,如前所述http://gruntthepeon.free.fr/ssemath/是一个很好的资源。根据精度的重要性,可以使术语数量更低。 – 2015-04-12 23:18:01

1
的ssemath库

的AVX版本现已推出:http://software-lisc.fbk.eu/avx_mathfun/

与库可以使用:

exp256_ps(y*log256_ps(x)); // for pow(x, y) 
+0

是的,这些为使用AVX的8个浮子提供了log,exp,sin,cos和sincos函数。不幸的是,相应的“双”版本仍然非常出色(我现在实际上更需要这些)。 – Walter 2017-03-29 19:50:18

+0

你可以试试Intel SPMD编译器:http://ispc.github.io/ispc.html文档说它支持pow和AVX – Pietro 2017-03-31 07:35:44