_addcarry_u64 и _addcarryx_u64 с MSVC и ICC
MSVC и ICC оба поддерживают внутренние _addcarry_u64
а также _addcarryx_u64
,
В соответствии с внутренним руководством Intel и техническим документом они должны соответствовать adcx
а также adox
соответственно. Однако, глядя на сгенерированную сборку, видно, что они отображаются на adc
а также adcx
соответственно и нет внутренней, которая отображается на adox
,
Кроме того, сообщаем компилятору о включении AVX2 с /arch:AVX2
в MSVC или -march=core-avx2
с ICC на Linux не имеет значения. Я не уверен, как включить ADX с MSVC и ICC.
Документация для списков MSVC _addcarryx_u64
с технологией ADX, тогда как _addcarry_u64
не имеет перечисленных технологий. Тем не менее, ссылка в документации MSVC на эти встроенные функции ведет непосредственно к руководству Intel Intrinsic, которое противоречит собственной документации MSVC и созданной сборке.
Из этого я делаю вывод, что внутреннее руководство Intel и технический документ ошибочны.
Это имеет некоторый смысл для MSVC, потому что он не позволяет встроенную сборку, это должно обеспечить способ использования adc
что это делает с _addcarry_u64
,
Одно из больших преимуществ adcx
а также adox
является то, что они работают на разных флагах CF
и переполнение OF
) и это позволяет две независимые параллельные цепи переноса. Тем не менее, поскольку нет adox
как это возможно? С ICC по крайней мере можно использовать встроенную сборку, но это невозможно с MSVC в 64-битном режиме.
Документация Microsoft и Intel (как официальный документ, так и внутреннее руководство) в настоящее время согласны.
_addcarry_u64
Внутренняя документация гласит, что производит только adc
, _addcarryx_u64
внутренний может производить либо adcx
или же adox
, С MSVC 2013 и 2015, однако, _addcarryx_u64
только производит adcx
, ICC производит оба.
2 ответа
Связанный, GCC не поддерживает ADOX и ADCX в настоящее время. "На данный момент" включает GCC 6.4 (Fedora 25) и GCC 7.1 (Fedora 26). GCC эффективно отключил встроенные функции, но все равно объявляет о поддержке, определяя __ADX__
в препроцессоре. Также см. Выпуск 67317 "Генерация глупого кода для _addcarry_u32/_addcarry_u64". Большое спасибо Си Руояо за то, что нашел проблему.
По словам Уроса Бизжака из списка рассылки справки GCC, GCC может никогда не поддерживать встроенные функции. Также см. GCC не генерирует ADCX или ADOX для _addcarryx_u64.
У Clang есть свои проблемы с ADOX и ADCX. Clang 3.9 и 4.0 дают сбой при попытке их использования. Также смотрите выпуск 34249 "Паника при использовании _addcarryx_u64 с Clang 3.9". По словам Крейга Топпера, это должно быть исправлено в Clang 5.0.
Мои извинения за размещение информации под вопросом MSVC. Это один из немногих хитов при поиске информации об использовании встроенных функций.
Они отображаются на 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]);
}