使用 gmp 固定大小的整数...?

Posted

技术标签:

【中文标题】使用 gmp 固定大小的整数...?【英文标题】:Fixed size integers with gmp...? 【发布时间】:2011-08-31 22:00:21 【问题描述】:

我几天来一直在尝试在 MINGW 下安装 GMP 库。我已经在 linux64 位环境下使用带有 gcc 的 __uint128_t 数周,然后在 GMP 和 mingw(32 位版本)下移植了相同的程序。我使用mpz_class 整数而不是__uint128_t。然后我开始了我的新程序,然后......!使用__uint128_t 和 64 位需要 16 分钟才能完成,使用 GMP 和 MINGW 需要 91 小时!!!

我应该怎么做才能加快速度?有没有更快的方法在 32 位环境下进行 128 位整数数学运算?我不需要超过 128 位,所以有什么方法可以告诉 GMP “好的,我只需要 128 位,保持精度固定但请快点”?

【问题讨论】:

128位需要做哪些操作? (+-</>*/,还有更有趣的吗?) 编译器原生支持 64 位。查找使用 32 位 uint 执行 64 位算术的代码,并使用这些原理为使用 64 位 uint 的 128 位 uint 实现它。它不会像原生 128 位支持那样快(你可以通过例如 SSE 获得),但它可能会比 libgmp 更快。 编译器可能支持 64 位,但在真正的 64 位环境(IOW、64 位寄存器以及更多好)。 【参考方案1】:

不,当您使用mpz_t 时,您不能将 GMP 限制为固定长度的整数。 mpz_t 是一个结构,其长度为肢体数组(已分配;已使用)和一个指向实际值的指针,该指针存储为整数数组(肢体;int32 或 int64 数组)。当任何值变大时,GMP 已准备好扩展任何值的长度。

您可以在初始化时为每个 mpz_t 分配 128 位,使用 mpz_init2

 mpz_init2(mpz_t*, bit_number);

但是由此带来的加速很小,仍然存在数据间接和长度处理。

你可以直接使用肢体,切换到mpn_低级函数:

http://www.gnu.org/software/gmp/manual/html_node/Low-level-Functions.html#Low-level%20Functions

不会有指向肢体的指针(这对缓存有好处),没有简单的输入/输出代码;并且没有自动肢体大小处理(也没有自动扩展;也没有分配)。您应该自己完成所有存储;甚至可能有些进位必须手动处理,但会有GMP的快速*/%操作;您可以使用mpz_t t;t._mp_size = t._mp_alloc=limb_number;t._mp_d=pointer_to_limb_array 重构 mpz_t 以便于输入/输出。

另外,如果你要切换到 64 位 mingw,你可以使用 uint128_t。

【讨论】:

而使用 mpz_init2 并分配 128 位会使其更快..? @Matteo 他说“但是由此带来的加速很小。” @Seth(谢谢,但他编辑了答案!:D我以前没见过!)【参考方案2】:

如果您的目标 Windows 计算机足够新,可以搭载 64 位 Windows(例如 Vista 或 7),您可以改用 MinGW-w64。

【讨论】:

以上是关于使用 gmp 固定大小的整数...?的主要内容,如果未能解决你的问题,请参考以下文章

使用非固定整数(int、long)而不是固定大小的整数(int64_t、int32_t)有啥好处吗?

GCC 中有固定大小的整数吗?

使用 mbed 框架在 STM32 上运行 GMP 的串行 printf

在独立程序中使用 GMP

使用 boost::spirit 解析任意精度整数

GMP 为中间计算创建的对象是不是保留在内存中?