是否有可能在 AVX/SSE 中获得多个正弦波?

Posted

技术标签:

【中文标题】是否有可能在 AVX/SSE 中获得多个正弦波?【英文标题】:Is it possible to get multiple sines in AVX/SSE? 【发布时间】:2015-01-13 23:24:50 【问题描述】:

我正在尝试编写一个 C++ 程序,它会启动我在 x64 汇编器中编写的函数。 我想稍微加快速度(并使用 CPU 功能),所以我选择使用向量运算。

问题是,我必须将正弦乘以一个整数,所以我必须先计算正弦。 是否可以在 SSE/AVX 中执行此操作?我知道指令fsin,但它不仅在 FPU 中,而且一次只计算 1 个正弦。所以我必须将它推入 FPU,调用fsin,将其从 FPU 弹出到内存,然后将其放入 AVX 寄存器中。在我看来,这不值得麻烦。

【问题讨论】:

看看这个库:gruntthepeon.free.fr/ssemath 您需要全精度吗? 【参考方案1】:

是的,有一个使用 SSE/AVX 的矢量版本! 但问题是必须使用 Intel C++ 编译器。

这称为英特尔小型向量数学库(内在):

对于 128 位 SSE,请使用(双精度):_mm_sin_pd

对于 256 位 AVX,请使用(双精度):_mm256_sin_pd

这两个内部函数实际上是非常小的函数,由手写的 SSE/AVX 程序集组成,现在您可以使用 AVX 一次处理 4 个正弦计算 :=) 延迟约为 10 个时钟周期(如果我没记错的话)在 Haswell CPU 上。

顺便说一句,CPU 需要执行大约 100 个这样的内在函数来预热并达到其峰值性能,如果只需要评估几个 sin 函数,最好使用普通的 sin() 代替。

祝你好运!

【讨论】:

【参考方案2】:

由于 OpenMP 4.0 需要矢量化 sin/cos 扩展,gcc-glibc 也在 libmvec 中提供了它们。见:

https://***.com/a/54355153 用于声明函数原型的头文件; https://sourceware.org/glibc/wiki/libmvec 了解 libmvec 是什么以及您通常如何使用它。

有关其他 SVML 替代方案的列表,请参阅 https://***.com/a/36637424。

【讨论】:

【参考方案3】:

SSE/AVX 中没有正弦指令,但是根据您需要的精度,您可以使用Taylor/Madhava series 将正弦函数的近似值写为多项式,或者使用Pade Approximant 作为两个多项式的商。当然还有更多多项式逼近技术。

这是否产生您想要的精度以及此方法的速度取决于您的确切问题。一般而言,多项式逼近非常快,因为可以使用 n FMA 指令(Pade 逼近也需要一次除法)计算第 n 次多项式,方法是

a+x*(b+x*(c+x*(...)))。

然而,众所周知,正弦在使用多项式逼近时表现不佳,因此用例有限。

【讨论】:

请检查intel SVML 是的,SVML 是一种处理方式,但它只是一个伪装成指令集的库。我决定基于 OP 想要仅使用汇编指令来解决这个问题的假设来回答这个问题,无论是出于娱乐还是教育目的:) 是的,我同意教育目的是有趣和重要的,但更重要的是,作者正在寻找一个解决方案:“是否有可能在 AVX/SSE 中获得多个正弦?”。 但我同意 sin() 没有直接的 AVX 硬件实现。 SVML 提供了一种利用 AVX 指令以 SIMD 方式并行处理许多常见数学函数的方法。 =) “正弦在使用多项式近似时表现不佳”任何来源?许多图书馆就是这样做的,例如github.com/microsoft/DirectXMath/blob/…

以上是关于是否有可能在 AVX/SSE 中获得多个正弦波?的主要内容,如果未能解决你的问题,请参考以下文章

如何讲正弦波转化为方波?频率不变。

在同一个 AVAudioPCMBuffer 中改变正弦波频率

Proteus仿真TLC5615输出1024点正弦波(振幅可调)

方波转成锯齿波和三角波的原理???

生成正弦波并在浏览器中播放[关闭]

生成正弦波:输出不正确