【问题标题】:Fast C code for simple fixed-(multi)-precision operations (add, div, mul, sub)? [closed]用于简单固定(多)精度操作(add、div、mul、sub)的快速 C 代码? [关闭]
【发布时间】:2013-05-08 10:45:40
【问题描述】:

我一直在编写一些 cython 代码来实现我想在 python 中使用的多精度数组运算(主要是点积和矩阵求逆)。我使用 mpfr 作为底层 C 库,通过在 C 和 Cython 中进行测试,我发现 mpfr(以 200 位精度)比 numpy(以机器精度)慢 50-200 倍(取决于操作)。我知道 mpfr 非常快,但我仍然发现这个开销非常大。由于我的需求非常有限(固定精度,只有基本操作,如加法、乘法等),我想知道我是否可以手动编写一些多精度操作(不考虑仔细舍入等)。不幸的是,这涉及很多工作,所以我希望在 C 或英特尔汇编中找到一些免费的代码 sn-ps 来进行基本的多精度算术。我将不胜感激任何提及后者或我应该或不应该采用这种方法的原因。

更新:我应该提到我已经尝试过 QD 库,它实际上(稍微)慢于类似精度(212 位)的 MPFR。我想这一定是由于 C++ 开销。

【问题讨论】:

  • 将 200 位精度与机器精度进行比较,就是将苹果与橙子进行比较。 50-200 倍的速度惩罚对我来说似乎并不罕见。即使您只想支持像乘法这样的“简单”操作,我怀疑您会打败它。
  • 我不明白为什么有些用户投票结束这个问题。它有什么问题? OP 正在使用 MPFR,但发现它超出了她/他的需要。 OP 非常清楚,他/她期望能够更快地为他/她找到的原因是他/她没有使用 MPFR 提供的所有功能。事实证明,其他人已经感受到了同样的需求,甚至至少存在一种即用型替代方案。
  • @MatthewD 双双加法需要一些双加法来计算。如果 FMA 指令可用(如在 PowerPC 处理器和最近的 Intel/AMD 桌面处理器中发现的),双双乘法也只需要几条指令。
  • 感谢 Pascal,这正是我的推理。我已经看到(在另一个 SO 线程上)有人为 128 位操作提供了一些 CUDA 汇编指令,他们声称这是大约 16 条指令,所以我希望减速的顺序而不是 100-200 次。即使使用 120 位,我的速度也会显着下降 (60-100x)。
  • 尝试分析您的程序以找出哪些 MPFR 函数使用时间最长。

标签: c assembly arbitrary-precision


【解决方案1】:

您可以尝试使用 double-doublequad-double 库。这些库利用现有的双精度硬件来提高速度(我写了一个摘要作为我自己的question 的一部分)。后者似乎有code

这些库需要底层硬件完全按照 IEEE 754 标准的要求运行。如果计算过于精确,它们就会崩溃。如果您以现代桌面处理器为目标,请确保您的编译器为浮点计算生成 SSE2 指令。如果由于某种原因你被 8087 指令卡住了,你最好使用双双扩展库(数字表示为两个 80 位数字的总和)。 CRlibm 中有一个应该不需要太多工作就可以出来。


另外,可能值得尝试 GMP 的 MPF 类型。它可能会更快,因为它不会像 MPFR according to the latter's FAQ 那样好。

【讨论】:

  • 我没有仔细研究过这个问题,我假设舍入问题只影响最低有效位是否正确?如果是这样,那么它们与我几乎无关,因为我只需要提高精度(超出机器精度),但可以承受最低有效位的舍入误差。实际上,我确实测试了 QD 和 MPFR,它总是 较慢(MPFR 为 212 位)。这证明了 MPFR 令人印象深刻的优化(或 QD 的 C++ 开销)。
  • @user2153813 双双或四双库不会尝试提供完美的 IEEE 754 样式浮点运算。特别是,一个技巧是避免在一些中间步骤上进行重整化,用性能换取几位精度(程序员需要自己跟踪丢失的位数)。这个技巧在 CRlibm 中使用。调查您的问题,我发现了这一点,这表明 GMP 的 MPF 类型可能比 MPFR 更快,因为它并没有试图变得那么好:mpfr.org/faq.html#mpfr_vs_mpf
  • MPF 可能会有所改善,但从谷歌搜索来看,差异可能是 20%,而我正在寻找 x3-6 的加速。一个大问题是 MPFR 和 GMP 都使用任意精度,因此在内部将数字存储为指向数组的指针。因为我可以在编译时修复精度,所以我可以将数字存储在结构中。这在进行大型点积时可能非常重要,因为所有访问都将在连续内存中。我想要像 QD 这样的东西,但由于某种原因,QD 比 MPFR 慢。所以我现在只是在寻找一些 C 代码来让我开始编写自己的代码。
  • 为了澄清上述内容:我想要一些简单的基线代码来评估 MPFR 的开销,以确定它是否值得编写我自己的 MP func,我还可以针对数组访问(即 MP 点积)进行优化)。我可以从您指向的 qd.pdf 文件中的算法开始,但我希望从一些实际代码开始。我会检查 CRlibm。谢谢大家的建议!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-18
  • 1970-01-01
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
  • 2020-05-22
相关资源
最近更新 更多