Есть ли проблемы совместимости с clang-cl и arch: avx2? - PullRequest
1 голос
/ 21 июня 2020

Я использую Windows 10, Visual Studio 2019, Platform: x64, и у меня есть следующий тестовый сценарий в однофайловом решении Visual Studio:

#include <iostream>
#include <intrin.h>
using namespace std;

int main() {
    unsigned __int64 mask = 0x0fffffffffffffff; //1152921504606846975;
    unsigned long index;

    _BitScanReverse64(&index, mask);
    if (index != 59) {
        cout << "Fails!" << endl;
        return EXIT_FAILURE;
    }
    else {
        cout << "Success!" << endl;
        return EXIT_SUCCESS;
    }
}

В моем решении свойства я установите для параметра «Включить расширенный набор команд» значение «Расширенные векторные расширения 2 (/ arch: AVX2)». При компиляции с помощью msv c (установка «Platform Toolset» на «Visual Studio 2019 (v142)») код возвращает EXIT_SUCCESS, но при компиляции с помощью clang-cl (установка «Platform Toolset» на «LLVM (clang-cl)» ) Я получаю EXIT_FAILURE. При отладке выполнения clang-cl значение индекса равно 4, тогда как оно должно быть 59. Это наводит на мысль, что clang-cl читает биты в направлении, противоположном MSV C.

Это это не тот случай, когда я устанавливаю «Включить расширенный набор команд» на «Не задано». В этом сценарии и MSV C, и clang-cl возвращают EXIT_SUCCESS.

Все библиотеки DLL загружаются и отображаются в окне вывода отладки из C: \ Windows \ System32 ###. Dll во всех случаях.

Кто-нибудь понимает такое поведение? Я был бы признателен за любую информацию здесь.

РЕДАКТИРОВАТЬ: Я не упомянул ранее: я скомпилировал это с процессором IntelCore i7-3930K @ 3,20 ГГц.

1 Ответ

4 голосов
/ 21 июня 2020

Получение 4 вместо 59 звучит как clang _BitScanReverse64 как 63 - lzcnt. Фактический bsr медленный на AMD, поэтому да, есть причины, по которым компилятор может захотеть скомпилировать встроенный c BSR в другую инструкцию.

Но затем вы запустили исполняемый файл на компьютере который на самом деле не поддерживает BMI, поэтому lzcnt декодируется как rep bsr = bsr, давая счетчик ведущих нулей вместо битового индекса самого высокого установленного бита.

AFAIK, все процессоры с AVX2 также имеют BMI. Если в вашем процессоре этого нет, вам не следует ожидать, что ваши исполняемые файлы, собранные с /arch:AVX2, будут правильно работать на вашем процессоре. И в этом случае режим отказа не был незаконной инструкцией, он был lzcnt запущен как bsr.

MSV C обычно не оптимизирует встроенные функции, очевидно, включая этот случай, поэтому он просто использует bsr напрямую.

Обновление: i7-3930K - это SandyBridge-E. У него нет AVX2, так что это объясняет ваши результаты.

clang-cl не вызывает ошибки, когда вы говорите ему создать исполняемый файл AVX2 на компьютере, отличном от AVX2. Примером использования для этого будет компиляция на одной машине для создания исполняемого файла для запуска на разных машинах.

Это также не добавляет код проверки CPUID в ваш исполняемый файл за вас. Если хотите, напишите сами. Это C ++, он вас за руку не держит.

параметры целевого процессора

MSV C -style /arch параметры гораздо более ограничены, чем обычный стиль GCC / clang. Их нет для разных уровней SSE, таких как SSE4.1; он переходит прямо к AVX.

Кроме того, /arch:AVX2 очевидно подразумевает BMI1 / 2, хотя это разные наборы инструкций с разными битами функций CPUID. Например, в коде ядра вам могут понадобиться целочисленные инструкции BMI, но не инструкции SIMD, которые касаются регистров XMM / YMM.

clang -O3 -mavx2 не также включает -mbmi. Обычно вы этого захотите, но если бы вам не удалось также включить BMI, clang застрял бы с использованием bsr. (Что на самом деле лучше для процессоров Intel, чем 63-lzcnt). Я думаю, что MSV C / arch: AVX2 - это что-то вроде -march=haswell, если он также включает инструкции FMA.

И ничто в MSV C не поддерживает оптимизацию двоичных файлов для запускать на компьютере, на котором вы их собираете . В этом есть смысл, он разработан для модели разработки программного обеспечения с закрытым исходным кодом.

Но G CC и clang имеют -march=native, чтобы включить все наборы инструкций на вашем компьютере. поддерживает. И, что немаловажно, установите параметры настройки , подходящие для вашего компьютера. например, не беспокойтесь о создании кода, который будет медленным на процессоре AMD или на старом Intel, просто сделайте asm, который подходит для вашего CPU.

TL: DR: параметры выбора процессора in clang-cl очень грубые, объединяющие не-SIMD-расширения с некоторым уровнем AVX. Вот почему /arch:AVX2 включает целочисленное расширение BMI, а clang -mavx2 не поддерживает.

...