的Visual C ++ 64位有进位加 [英] Visual C++ x64 add with carry

查看:443
本文介绍了的Visual C ++ 64位有进位加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因为似乎没有成为一个内在的ADC和I不能使用内联汇编的x64体系结构使用Visual C ++,我应该怎么做,如果我想用加有进位写一个函数,但其​​包含在C ++的命名空间?

Since there doesn't seem to be an intrinsic for ADC and I can't use inline assembler for x64 architecture with Visual C++, what should I do if I want to write a function using add with carry but include it in a C++ namespace?

(与比较运算符仿效是不是一种选择,这256兆补充的是性能的关键。)

(Emulating with comparison operators is not an option. This 256 megabit add is performance critical.)

推荐答案

有现在是禀 ADC 在MSVC: _addcarry_u64 。下面code

There is now an instrinsic for ADC in MSVC: _addcarry_u64. The following code

#include <inttypes.h>
#include <intrin.h>
#include <stdio.h>

typedef struct {
    uint64_t x1;
    uint64_t x2;
    uint64_t x3;
    uint64_t x4;
} uint256;

void add256(uint256 *x, uint256 *y) {
    unsigned char c = 0;
    c = _addcarry_u64(c, x->x1, y->x1, &x->x1);
    c = _addcarry_u64(c, x->x2, y->x2, &x->x2);
    c = _addcarry_u64(c, x->x3, y->x3, &x->x3);
    _addcarry_u64(c, x->x4, y->x4, &x->x4);
}

int main() {
    //uint64_t x1, x2, x3, x4;
    //uint64_t y1, y2, y3, y4;
    uint256 x, y;
    x.x1 = x.x2 = x.x3 = -1; x.x4 = 0;
    y.x1 = 2; y.x2 = y.x3 = y.x4 = 0;

    printf(" %016" PRIx64 "%016" PRIx64 "%016" PRIx64 "%016" PRIx64 "\n", x.x4, x.x3, x.x2, x.x1);
    printf("+");
    printf("%016" PRIx64 "%016" PRIx64 "%016" PRIx64 "%016" PRIx64 "\n", y.x4, y.x3, y.x2, y.x1);
    add256(&x, &y);
    printf("=");
    printf("%016" PRIx64 "%016" PRIx64 "%016" PRIx64 "%016" PRIx64 "\n", x.x4, x.x3, x.x2, x.x1);
}

产生以下汇编输出从Visual Studio防爆preSS 2013

produces the following assembly output from Visual Studio Express 2013

mov rdx, QWORD PTR x$[rsp]
mov r8, QWORD PTR x$[rsp+8] 
mov r9, QWORD PTR x$[rsp+16]
mov rax, QWORD PTR x$[rsp+24]
add rdx, QWORD PTR y$[rsp]
adc r8, QWORD PTR y$[rsp+8]
adc r9, QWORD PTR y$[rsp+16]
adc rax, QWORD PTR y$[rsp+24]

有一个添加 ADC 预期。

编辑:

似乎有一些混乱,以什么 _addcarry_u64 一样。如果你看看这个,我挂在这个答案的开始微软的文档,它表明,它不需要任何特殊的硬件。这将产生 ADC ,也将努力在所有的x86-64处理器(和 _addcarry_u32 将工作在更老的处理器)。它工作正常的Ivy Bridge的系统上我测试。

There seems to be some confusion as to what _addcarry_u64 does. If you look at Microsoft's documentation for this which I linked to at the start of this answer it shows that it does not require any special hardware. This produces adc and it will work on all x86-64 processors (and _addcarry_u32 would work on even older processors). It works fine on the Ivy Bridge system I tested it on.

不过, _addcarryx_u64 确实需要 ADX (如图MSFT的文档),实际上它无法运行我Ivy Bridge的系统。

However, _addcarryx_u64 does require adx (as shown in MSFT's documentation) and indeed it fails to run on my Ivy Bridge System.

这篇关于的Visual C ++ 64位有进位加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆