SSE类型的pow函数

9
我使用SSE类型进行一些显式向量化计算,例如__m128(在xmmintrin.h等中定义),但现在我需要将向量的所有元素提高到某个(相同)幂次方,即理想情况下我希望有类似于 __m128 _mm_pow_ps(__m128,float) 的东西,但不幸的是它并不存在。
如何解决这个问题?我可以存储向量,在每个元素上调用std::pow,然后重新加载它。这是最好的方法吗?编译器在自动向量化代码时调用std::pow时如何实现,否则可向量化的代码?是否有任何库提供有用的东西?
(请注意,这个问题相关但不是重复的,当然也没有一个有用的答案。)

我曾经使用过http://gruntthepeon.free.fr/ssemath/来进行`exp/log`计算,并在无法进行自动向量化时将`pow(x,k)`写成`exp(k*log(x))`。不确定它与自动向量化代码相比如何。 - SleuthEye
3
您可以使用Agner Fog的向量类。他为SSE、AVX和AVX512提供了SIMD数学函数(包括pow、exp、log、sin等),适用于单精度浮点数和整数。我认为没有什么好的理由再使用Intel的SVML或AMD的libm了。 - Z boson
@Zboson,请问是否有一个支持SSE4的exp()函数的好的C库? - Royi
4个回答

9

我看了一下那个库。它似乎只限于gcc,只知道SSE2,并且代码中的文档很差。我还想要它支持AVX类型__m256__m256d - Walter
@Walter在MSVC上运行良好(请注意链接底部的VS2010基准测试),当查看cephes库时,代码变得更加清晰,这似乎是主要灵感来源。 - SleuthEye
我需要它能够与gcc、icc和clang一起工作。原始的cehpes库非常好!如果没有更好的选择,我至少可以按照这些库的思路实现自己的log和exp函数。 - Walter
@Walter,你有没有尝试编译我提供的库?大约有5行与编译器相关的代码,它们应该可以在你提到的所有编译器上运行。 - Jasper Bekkers
抱歉,前几天有其他事情要处理。但是这个库不支持我需要的所有向量类型。 - Walter
使用这个公式,如何处理负数? - Baptiste Wicht

2

是的,这些使用AVX为8个“float”提供了log、exp、sin、cos和sincos函数。不幸的是,相应的“double”版本仍然未完成(实际上我现在更需要它们)。 - Walter
你可以尝试使用Intel SPMD编译器:http://ispc.github.io/ispc.html,文档显示它支持pow和AVX。 - Pietro

2

2
SVML在gcc中非常有用。gcc -mveclibabi=svml甚至可以让向量化程序创建对vmlsPow4等函数的调用。 - Marc Glisse
@MarcGlisse,gcc是否包含Intel SVML内置? - Royi
1
gcc 不包括 SVML,它只知道如何生成对它的调用,如果你保证将其可用于链接。 - Marc Glisse

-2
将浮点数转换为向量。
 _mm_pow_ps(v,_mm_ps1(f))

1
很抱歉,没有 _mm_pow_ps() 这个函数。否则我也不会问了。 - Walter
啊,我误解了问题。正如之前提到的那样,泰勒级数是传统的方法,http://gruntthepeon.free.fr/ssemath/ 是一个很好的资源。根据精度的重要性,您可以将项数大大降低。 - Johan Köhler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接