MSVC和ICC都支持内在函数_addcarry_u64
和_addcarryx_u64
。
根据Intel's Intrinsic Guide和white paper,这些应分别映射到adcx
和adox
。但是,通过查看生成的程序集,很明显它们分别映射到adc
和adcx
,并且没有内在映射到adox
。
此外,告诉编译器在MSVC中使用
我不确定如何使用MSVC和ICC启用ADX。/arch:AVX2
或在Linux上使用ICC启用-march=core-avx2
的AVX2没有任何区别。
documentation for MSVC使用ADX技术列出_addcarryx_u64
,而_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生产两者。
答案 0 :(得分:3)
他们映射到adc
,adcx
和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]);
}
答案 1 :(得分:3)
相关,GCC目前不支持ADOX和ADCX。 &#34;目前&#34;包括GCC 6.4(Fedora 25)和GCC 7.1(Fedora 26)。 GCC有效地禁用了内在函数,但它仍然通过在预处理器中定义__ADX__
来宣传支持。另请参阅Issue 67317, Silly code generation for _addcarry_u32/_addcarry_u64。非常感谢习若愚找到了这个问题。
根据GCC帮助邮件列表中的Uros Bizjak,GCC可能会never support the intrinsics。另请参阅GCC does not generate ADCX or ADOX for _addcarryx_u64。
Clang在ADOX和ADCX方面有一系列问题。 Clang 3.9和4.0在尝试使用它们时崩溃。另请参阅Issue 34249, Panic when using _addcarryx_u64 with Clang 3.9。根据Craig Topper的说法,它应该在Clang 5.0中修复。
我很抱歉在MSVC问题下发布信息。这是搜索有关使用内在函数的信息时为数不多的点击之一。