使用 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)有啥好处吗?