visual c ++

MSVC和ICC都支持内部函数_addcarry_u64_addcarryx_u64

根据英特尔的固有指南和白皮书,这些应分别映射到adcxadox 。 但是,通过查看生成的程序集,可以清楚地看到它们分别映射到adcadcx并且没有映射到adox内在。

此外,告诉编译器在MSVC中使用/arch:AVX2启用AVX2,或者在Linux上使用ICC启用-march=core-avx2并没有区别。 我不确定如何使用MSVC和ICC启用ADX。

MSVC文档使用ADX技术列出_addcarryx_u64 ,而_addcarry_u64没有列出的技术。 但是,这些内在函数的MSVC文档中的链接直接指向与MSVC自己的文档和生成的程序集相矛盾的Intel Intrinsic指南。

由此我得出结论:Intel的Intrinsic指南和白皮书是错误的。

这对于MSVC意义上说是有道理的,它不允许内联汇编,它应该提供一种使用adc ,它使用_addcarry_u64

adcxadox一大优势是它们在不同的标志上运行(带有CF和溢出OF ),并允许两个独立的并行进位链。 但是,由于adox没有固有的adox ,这怎么可能? 对于ICC,至少有一个可以使用内联汇编,但这在64位模式下不适用于MSVC。


微软和英特尔的文档(包括白皮书和在线内部指南)都同意了。

_addcarry_u64内在文档说只生成adc_addcarryx_u64内部可以生成adcxadox 。 但是,对于MSVC 2013和2015, _addcarryx_u64只生成adcx 。 ICC同时生产。


他们映射到adcadcxadox 。 编译器根据您的使用方式决定使用哪些指令。 如果您并行执行两个big-int附加,编译器将使用adcxadox ,以获得更高的吞吐量。 例如:

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]);
}

相关的,GCC目前不支持ADOX和ADCX。 “目前”包括GCC 6.4(Fedora 25)和GCC 7.1(Fedora 26)。 GCC有效地禁用了内在函数,但它仍然通过在预处理器中定义__ADX__来通告支持。 另请参阅问题67317,_addcarry_u32 / _addcarry_u64的愚蠢代码生成。 非常感谢奚若瑶发现这个问题。

根据GCC Help邮件列表中的Uros Bizjak,GCC可能永远不会支持内部函数。 另请参阅GCC不为_addcarryx_u64生成ADCX或ADOX。

Clang在ADOX和ADCX方面有自己的一套问题。 叮当3.9和4.0试图使用它们时崩溃。 另请参阅问题34249,在Clang 3.9中使用_addcarryx_u64时出现恐慌。 根据Craig Topper的说法,它应该在Clang 5.0中修复。

我很抱歉发布MSVC问题下的信息。 这是搜索有关使用内在函数的信息时为数不多的命中之一。

链接地址: http://www.djcxy.com/p/84259.html

上一篇: visual c++

下一篇: C# Parallel.Foreach equivalent in Python