【问题标题】:How to add 3 large integers efficiently using GMP如何使用 GMP 有效地添加 3 个大整数
【发布时间】:2018-12-26 14:30:45
【问题描述】:

我想对 ~2048 位有符号整数执行 x = a + b + c。目前我的代码看起来像

mpz_add(x, a, b);
mpz_add(x, x, c);

是否有一个函数可以做到这一点?这在我的应用程序中发生了很多次。我已经分析了我的代码,并且 3 路添加步骤占用了运行时的很大一部分。如果有另一种方法可以一次性完成此操作,可能会有所帮助。

【问题讨论】:

  • 我认为适当的operator+()overload 不会对gmp 的性能产生任何显着影响。
  • 是的,运算符重载只是一些语法糖。底层算法可以一次迭代四肢,而我的想法是两次。
  • 没有上下文很难回答。 x 每次都是一些新变量,还是您在循环中重复使用的变量?所有数字的大小/符号是否相同?等等。我怀疑 3 路加法器有什么好处,但谁知道呢……您的分析器是否指定了 mpz_add 的哪个部分需要时间?
  • 人们认为评估中的临时变量将成为 C++ 的一个问题,但 gmpxx 库为此类表达式精心设计,并采用了移动语义等现代技术。

标签: c++ performance gmp bignum


【解决方案1】:

我已广泛使用 MPFR,并且几乎浏览了文档的每个部分。我几乎可以肯定 MPFR 中不存在这样的东西,因此,我几乎可以肯定 GMP 中不存在这样的东西。

一种解决方案可能是切换到 MPFR 并使用 Pavel Holoborodko's MPFR C++,它为 MPFR 函数添加了运算符。我无法想象这会提高性能(尽管它可能不会对其产生太大影响),它在 GPL 下,您必须安装另一个库,但它会结合操作。

我不知道有什么快速算法可以在添加三个数字时不只是将其中两个相加,然后在幕后添加最后一个数字。我认为使用任何语言的任何库将这两个操作组合成一个操作不会有助于提高性能。即使使用 GNU MP,任意精度也很慢。如果有帮助,我在 Code Review 上比较了 here 的速度。

【讨论】:

    【解决方案2】:

    调用两次函数不会产生明显的开销。但是,如果需要,重新分配 x 可能会非常缓慢。为避免这种情况,您可以测量 a、b 和 c 的大小,并确保 x 已分配三个数字中的最大大小加上 2(在最坏的情况下,加 1 位)。你可以使用

    mpz_init2(x, maxsize+2);
    

    或者,如果 x 已经初始化,

    if (mpz_sizeinbase(x, 2) < maxsize+2)
      mpz_realloc2(x, maxsize+2);
    

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 2021-11-12
      • 1970-01-01
      • 2011-07-22
      • 1970-01-01
      相关资源
      最近更新 更多