【问题标题】:Logarithm with SSE, or switch to FPU?使用 SSE 对数,还是切换到 FPU?
【发布时间】:2025-12-29 21:20:17
【问题描述】:

我正在做一些统计计算。我需要它们快速,所以我重写了大部分以使用 SSE。我对它很陌生,所以我想知道这里的正确方法是什么:

据我所知,SSE 中没有 log2 或 ln 函数,至少没有到 4.1,这是我使用的硬件支持的最新版本。

是不是更好:

  1. 提取 4 个浮点数,并对它们进行 FPU 计算以确定熵 - 我不需要将任何这些值加载回 SSE 寄存器,只需将它们相加到另一个浮点数
  2. 为 SSE 找到一个执行 log2 的函数

【问题讨论】:

  • 您的 log2 需要什么样的范围和精度?
  • 我从 FPU 获得的准确度是可取的
  • 周围似乎有一些 SSE log2 实现,例如jrfonseca.blogspot.com/2008/09/…
  • 很好,谢谢!我会尝试并对其进行基准测试。将浮点数提取到一个数组中,然后通过 FPU 对其执行 4 个连续的 log2 操作,速度慢得令人失望。 Instruments 表示,它在那里浪费了 95% 的时间。
  • 哇...我尝试了您链接的博客中的实现,我可以尽可能接近。它很快。将处理时间缩短至约 10%。非常感谢!

标签: sse simd logarithm natural-logarithm


【解决方案1】:

周围似乎有一些 SSE log2 实现,例如this one.

还有Intel Approximate Maths Library,其中有一个log2 函数-它是旧的(2000 年),但它是SSE2,它应该仍然可以正常工作。


也可以看看:

【讨论】:

  • 由于博客上使用的方法,该函数现在是内存绑定,而不是 CPU 绑定。我稍微展开循环以利用一些 _mm_prefetch 爱,它仍然受内存限制。感谢您的精彩指针!
  • 很高兴它对你有用。您可能已经知道这一点,但如果您遇到内存带宽瓶颈,请尝试将其他操作与您的 log2 结合起来,以便在缓存中更多地使用数据。
  • 如果您正在更新您的答案,您可能需要提及 libmvec,它与最近的 glibc 一起提供。
【解决方案2】:

没有实现对数函数的 SSE 指令。但是,也没有单个 x86 指令可以执行通用对数。如果您正在考虑使用 C 标准库中的 loglog10 之类的对数函数,那么值得看看在 libc 等开源库中使用的实现。您可以轻松滚动您自己的对数近似值,该对数近似值在 SSE 寄存器中的所有元素上运行。

这样的函数通常使用多项式逼近来实现,该多项式逼近在输入参数的特定区域(例如泰勒级数)的某个精度规范内有效。然后,您可以利用对数属性将通用输入参数包装到对数例程的可接受输入范围内。此外,您可以利用以下属性参数化对数的底:

log_y(x) = log_a(x) / log_a(y)

其中a 是您创建的对数例程的基数。

【讨论】: