Z b*_*son 7 assembly icc intrinsics visual-c++ adx
MSVC和ICC都支持内在函数_addcarry_u64
和_addcarryx_u64
.
根据英特尔的内在指南和白皮书,这些应分别映射到adcx
和adox
.但是,通过查看生成的程序集,很明显它们分别映射到adc
并且adcx
没有映射到的内在函数adox
.
另外,告诉编译器
我不确定如何使用MSVC和ICC启用ADX./arch:AVX2
在MSVC中启用AVX2 或-march=core-avx2
在Linux上启用ICC没有任何区别.
MSVC的文档列出_addcarryx_u64
了ADX技术,_addcarry_u64
但没有列出的技术.但是,MSVC针对这些内在函数的文档中的链接直接指向Intel Intrinsic指南,该指南与MSVC自己的文档和生成的程序集相矛盾.
由此我得出结论,英特尔的内在指南和白皮书是错误的.
这对于MSVC感觉有一定意义,它不允许内联汇编它应该提供一种使用adc
它的方式_addcarry_u64
.
其中的一大优点adcx
,并adox
为他们在不同的标志(进操作CF
和溢出OF
),这使得两个独立平行进位链.但是,由于没有内在的adox
可能性如何?对于ICC,至少有一个可以使用内联汇编,但在64位模式下使用MSVC是不可能的.
微软和英特尔的文档(白皮书和在线内在指南)都同意了.
该_addcarry_u64
征的文件说只生产adc
.该_addcarryx_u64
征可以产生两种adcx
或adox
.然而,在MSVC 2013和2015中,_addcarryx_u64
只生产adcx
.ICC同时生产.
相关的是,GCC 目前不支持 ADOX 和 ADCX。“目前”包括 GCC 6.4 (Fedora 25) 和 GCC 7.1 (Fedora 26)。GCC 有效地禁用了内部函数,但它仍然通过__ADX__
在预处理器中定义来宣传支持。另请参阅问题 67317,_addcarry_u32/_addcarry_u64 的愚蠢代码生成。非常感谢奚若瑶发现问题。
根据 GCC 帮助邮件列表上的 Uros Bizjak 的说法,GCC 可能永远不会支持内在函数。另请参阅GCC 不会为 _addcarryx_u64 生成 ADCX 或 ADOX。
Clang 在 ADOX 和 ADCX 方面有自己的一系列问题。尝试使用 Clang 3.9 和 4.0 时会崩溃。另请参阅问题 34249,将 _addcarryx_u64 与 Clang 3.9 一起使用时出现恐慌。根据 Craig Topper 的说法,它应该在 Clang 5.0 中得到修复。
对于在 MSVC 问题下发布信息,我深表歉意。这是搜索有关使用内在函数的信息时为数不多的命中之一。
小智 5
它们映射到adc
, adcx
AND adox
。编译器根据您如何使用指令来决定使用哪些指令。如果并行执行两个 big-int 加法,编译器将使用adcx
和adox
,以获得更高的吞吐量。例如:
unsigned char c1 = 0, c2 = 0
for(i=0; i< 100; i++){
c1 = _addcarry_u64(c1, res[i], a[i], &res[i]);
c2 = _addcarry_u64(c2, res[i], b[i], &res[i]);
}
Run Code Online (Sandbox Code Playgroud)