2011-02-24 44 views
7

我正在计算高度并行化的trig函数(在像1024的块中),并且我想利用至少一些现代体系结构所具有的并行性。C中的矢量化Trig函数?

当我编译块

for(int i=0; i<SIZE; i++) { 
    arr[i]=sin((float)i/1024); 
} 

GCC不会向量化它,并说

not vectorized: relevant stmt not supported: D.3068_39 = __builtin_sinf (D.3069_38); 

这对我来说很有意义。但是,我想知道是否有一个库来执行并行触发计算。

只有一个简单的泰勒系列上升到第11位,GCC将向量化所有的循环,并且我的速度比无辜罪循环快两倍(具有比特精确的答案,或者9阶系列,对于1600倍数值中的最后两个,只有一个比特关闭,对于> 3倍加速)。我确定以前有人遇到过这样的问题,但是当我google时,我发现没有提及任何库或类似的东西。

A.有没有东西存在? B.如果不是,建议优化并行触发函数?

编辑:我发现了以下库称为“SLEEF”:http://shibatch.sourceforge.net/它在this论文中描述,并使用SIMD指令来计算几个基本功能。它使用SSE和AVX特定代码,但我认为将其转换为标准C循环并不困难。

回答

1

您使用的平台是?这种类型的许多库已经存在:

  • 英特尔提供了带有icc的矢量数学库(VML)。
  • Apple提供了vForce库作为Accelerate框架的一部分。
  • HP为Itanium提供了自己的矢量数学库(也可能是其他架构)。
  • Sun提供了libmvec及其编译器工具。
  • ...
+0

我在Debian/Linux的x86_64的,GCC。理想情况下,我希望能在GCC支持矢量化的大多数平台上运行。 – 2011-02-24 20:29:27

2

既然你正在寻找在这里计算的谐波,我有一些code that addressed a similar problem。它的矢量化速度已经超过我发现的任何其他东西。作为一个好处,你可以免费获得余弦。

+0

不错,但我想要一些比装配更便携的东西。 – 2011-02-24 20:40:59

+0

在这种情况下,我会强烈推荐NETLIB。您可以在AMD的framewave库中找到一个很好的实现:http://framewave.svn.sourceforge.net/viewvc/framewave/trunk/Framewave/domain/common/include/Trigonometric_NETLIB.h?revision=HEAD&view=markup – Seth 2011-02-24 20:48:48

3

既然你说像有一些选项你使用GCC它看起来:

这就是说,我可能会考虑GPGPU解决的办法。也许写在CUDA或OpenCL(如果我没有记错CUDA支持正弦函数)。以下是一些看起来可能会更容易的库。

+1

OpenCL提供了向量为所有数学函数重载。我相信CUDA也是如此。 – 2011-02-24 21:32:53

1

取而代之的是泰勒级数的,我想看看fdlibm使用的算法。他们应该以更少的步骤获得尽可能多的精度。

+0

fdlibm只是使用多项式近似:http://www.netlib.org/fdlibm/k_sin.c – 2011-03-24 00:57:10

+2

@JeremySalwen ...但这些多项式的系数不是从泰勒级数中得出的;他们被选择使用更微妙的方法:http://en.wikipedia.org/wiki/Minimax_approximation_algorithm。如果你看看比k_sin.c更难的k_cos.c,因为较大的参数使得一个大的ULP计算得到一个小的结果,而这个小的结果对于一个小的ULP来说是精确的,你会注意到一个有趣的补偿技术,它使矢量化棘手。 – 2013-09-09 13:50:41