问题描述
在任意precision运算(例如512位整数)的工作,有没有什么办法让GCC使用ADC和类似的指令,而无需使用内联汇编?
When working with arbitrary precision arithmetic (e.g. 512-bit integers), is there any way to get GCC to use ADC and similar instructions without using inline assembly?
在GMP的源$ C $ C一乍一看表明,他们根本装配的实现为每个支持的平台。
A first glance at GMP's sourcecode shows that they simply have assembly implementations for every supported platform.
下面是测试code我写的,它的命令行增加了两个128位的数字和输出结果。 (由微型GMP的add_n启发):
Here is the test code I wrote, which adds two 128-bit numbers from the command line and prints the result. (Inspired by mini-gmp's 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(海湾合作委员会)4.5.2
。
GCC -O3 -std=c99
Does not produce any adc
instructions, as checked by objdump
. My gcc version is i686-pc-mingw32-gcc (GCC) 4.5.2
.
推荐答案
GCC的将会的使用进位标志的如果的就可以看到,它需要:结果
当在32位计算机上添加两个 uint64_t中
值,例如,这必须导致一个32位的添加
加上一个32位的 ADC
。但是,除了那些情况下,如果编译器被强制使用随身携带,它可能无法劝他这样做W / O汇编。因此,它可能是有利的使用可提供的最大的整数类型,以允许GCC通过有效地让它知道的值的单个组件属于在一起以优化操作
GCC will use the carry flag if it can see that it needs to:
When adding two uint64_t
values on a 32-bit machine, for example, this must result in one 32-bit ADD
plus one 32-bit ADC
. But apart from those cases, where the compiler is forced to use the carry, it probably cannot be persuaded to do so w/o assembler. Therefore, it may be beneficial to use the biggest integer type available to allow GCC to optimize operations by effectively letting it know that the single 'components' of the value belong together.
对于简单的加法,另一种方式来计算进可以看看相关位的操作数,如:
For the simple addition, another way to calculate the carry could be to look at the relevant bits in the operands, like:
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) );
这篇关于获取GCC要使用进位逻辑任意precision算法,而不内联汇编?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!