C中的多字加法

时间:2014-03-02 09:47:24

标签: c math gcc optimization bit-manipulation

我有一个使用GCC __uint128_t的C程序很棒,但现在我的需求已经超越了它。

对于196或256位的快速算术,我有哪些选择?

我需要的唯一操作是加法(我不需要进位,即,我将使用mod 2 ^ 192或2 ^ 256)。

速度很重要,所以如果可能的话,我不想转向一般的多精度。 (实际上我的代码确实在某些地方使用了多精度,但这是在关键循环中并且将运行数百亿次。到目前为止,多精度需要运行数万次。)

也许这很简单,可以直接编码,或者我需要找一些合适的库。

你的建议是什么,哦,Stack Overflow?

澄清:GMP对我的需求来说太慢了。虽然我实际上在我的代码中使用了multiprecision,但它不在内循环中并且运行时间少于10 ^ 5次。热循环运行更像10 ^ 12次。当我改变我的代码(增加一个尺寸参数)以使多精度部分比单精度运行更频繁时,我的速度减慢了100倍(主要是由于内存管理问题,我认为,而不是额外的μops)。我希望将其降低到4倍或更好。

2 个答案:

答案 0 :(得分:4)

256位版本

__uint128_t a[2], b[2], c[2];  // c = a + b
c[0] = a[0] + b[0];
c[1] = a[1] + b[1] + (c[0] < a[0]);

如果你在循环中多次使用它,你应该考虑通过SIMD和多线程使其并行

编辑:192位版本。通过这种方式,您可以消除128位比较,就像@ harold所说的那样:

struct __uint192_t {
    __uint128_t H;
    __uint64_t L;
} a, b, c;  // c = a + b
c.L = a.L + b.L;
c.H = a.H + b.H + (c.L < a.L);

答案 1 :(得分:2)

您可以测试来自this answer的“添加(low < oldlow)来模拟进位”技术是否足够快。这里low__uint128_t这可能会影响代码生成,这有点复杂。您也可以尝试使用4 uint64_t,我不知道这是好还是坏。

如果这还不够好,请放入内联汇编,并直接使用进位标志 - 它没有比这更好,但是你有使用内联汇编的常见缺点。