c - 让 GCC 在没有内联汇编的情况下使用进位逻辑进行任意精度运算?

标签 c optimization gcc compiler-optimization arbitrary-precision

在处理任意精度算术(例如 512 位整数)时,是否有任何方法可以让 GCC 在不使用内联汇编的情况下使用 ADC 和类似指令?

第一眼看 GMP 的源代码就会发现,它们只是为每个受支持的平台提供了汇编实现。

这是我写的测试代码,它从命令行将两个 128 位数字相加并打印结果。 (受 mini-gmp 的 add_n 启发):

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

int main (int argc, char **argv)
{
    uint32_t a[4];
    uint32_t b[4];
    uint32_t c[4];
    uint32_t carry = 0;

    for (int i = 0; i < 4; ++i)
    {
        a[i] = strtoul (argv[i+1], NULL, 16);
        b[i] = strtoul (argv[i+5], NULL, 16);
    }

    for (int i = 0; i < 4; ++i)
    {
        uint32_t aa = a[i];
        uint32_t bb = b[i];
        uint32_t r = aa + carry;
        carry = (r < carry);
        r += bb;
        carry += (r < bb);
        c[i] = r;
    }

    printf ("%08X%08X%08X%08X + %08X%08X%08X%08X =\n", a[3], a[2], a[1], a[0], b[3], b[2], b[1], b[0]);
    printf ("%08X%08X%08X%08X\n", c[3], c[2], c[1], c[0]);

    return 0;
}

GCC -O3 -std=c99 不生成任何 adc 指令,由 objdump 检查。我的 gcc 版本是 i686-pc-mingw32-gcc (GCC) 4.5.2

最佳答案

GCC 使用进位标志如果它可以看到它需要:
例如,当在 32 位机器上添加两个 uint64_t 值时,这必须导致一个 32 位 ADD 加上一个 32 位 ADC。但是除了那些编译器被迫使用进位的情况之外,可能无法说服它在没有汇编器的情况下这样做。因此,使用可用的最大整数类型可能有助于 GCC 通过有效地让其知道值的单个“组件”属于一起来优化操作。

对于简单的加法,计算进位的另一种方法是查看操作数中的相关位,例如:

uint32_t aa,bb,rr;
bool msbA, msbB, msbR, carry;
// ...

rr = aa+bb;

msbA = aa >= (1<<31); // equivalent: (aa & (1<<31)) != 0;
msbB = bb >= (1<<31);
msbR = rr >= (1<<31);


carry = (msbA && msbB) || ( !msbR && ( msbA || msbB) );

关于c - 让 GCC 在没有内联汇编的情况下使用进位逻辑进行任意精度运算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15696540/

相关文章:

c - 如何让这个简单的 C 程序重新开始?

c - 让 GCC 在 32 位代码 (-m32) 中使用 AVX?

c - GCC 不在 printf 中进行默认类型转换

c - 如何在运行时查找 MOSEK 符号常量?

c - 破坏红色区域的内联汇编

c - 使用时间溢出中断时出现故障

c - 我的代码有问题,我不确定我是否正确编写了它

c - n 个数字可能的三角形总数

c++ - Lambda 与手动内联代码更改 GCC 的优化器行为

C++:指针和编译器(别名?)优化