Как выполнить смешивание векторов AVX с собственным векторным синтаксисом clang (без встроенных функций)?

К моему удовольствию, я обнаружил, что clang позволяет писать явный векторный код, не прибегая к встроенным функциям, используя расширенные векторы.

Например, этот код:

typedef float floatx16 __attribute__((ext_vector_type(16)));

floatx16 add( floatx16 a, floatx16 b )
{
    return a+b;
}

...будет транслироваться непосредственно в одну инструкцию с вызовом clang -march=skylake-avx512:

vaddps  zmm0, zmm0, zmm1

Чтобы написать код без ветвлений, я хочу смешать векторы avx512. С внутренними функциями вы должны использовать встроенную функцию _mm512_mask_blend_ps. (Кстати, почему в AVX512 используется маска, порядок a, b, а в AVX используется порядок a, b, маска?)

Попытка сделать смесь с тернарным оператором не работает:

typedef float floatx16 __attribute__((ext_vector_type(16)));

floatx16 minimum( floatx16 a, floatx16 b )
{
    return a < b ? a : b;
}

...результат...

error: used type 'int __attribute__((ext_vector_type(16)))' (vector of 16 'int' values) where arithmetic or pointer type is required

Можно ли выполнить векторное смешивание, vblendmps zmm {k}, zmm, zmm, используя переменные ext_vector_type(16) в C?


person Bram    schedule 25.11.2020    source источник
comment
почему вы не хотите использовать встроенные функции и почему вы не используете фреймворк/библиотеку avx?   -  person bolov    schedule 25.11.2020
comment
float16 — очень запутанное имя типа. Большинство людей ожидает, что это будет означать скалярное 16-битное число с плавающей запятой половинной точности. Возможно floatx16? Что касается вашего фактического вопроса, IDK, clang вполне может оптимизировать некоторое ручное сравнение + AND / ANDN / OR в инструкции сравнения + blend со скалярной автовекторизацией или с собственными векторами GNU C / clang. (Или лучше, vaddps с маскированием слияния, в зависимости от того, с чем вы смешиваетесь.)   -  person Peter Cordes    schedule 25.11.2020
comment
Если бы вместо этого вы использовали vector_size, вы бы получили красиво векторизованный код как для gcc, так и для clang: godbolt.org/z/a73TG3   -  person chtz    schedule 25.11.2020
comment
@bolov, потому что a+b-c намного разборчивее, чем _mm256_sub_ps( _mm256_add_ps(a,b), c), и чем меньше фреймворков, тем лучше.   -  person Bram    schedule 25.11.2020
comment
@chtz Потрясающе! Если вы напишите это, я приму это как ответ. Бонусные очки, если можно вкратце коснуться разницы между ними, и почему их два?   -  person Bram    schedule 25.11.2020
comment
Встроенные функции @bolov работают только с одной архитектурой, тогда как векторный код работает с x86, ARM, PowerPC... автоматически   -  person phuclv    schedule 25.11.2020
comment
Версия gcc этих векторных расширений поддерживает только ?: в c++, а не c. Я не знаю, совместима ли в этом отношении реализация clang, потому что я отказываюсь ее использовать, так как она использует заведомо несовместимый синтаксис для перетасовок, поэтому для любого нетривиального векторного кода она полностью несовместима без всякой на то причины. .   -  person EOF    schedule 26.11.2020


Ответы (1)


(Это комментарий @chtz в форме ответа :)

Существует как минимум два разных способа создания векторных типов:

Форма А:

__attribute__ ( ( ext_vector_type(numelements) ) );

Форма Б:

__attribute__( ( vector_size(число байтов) ) );

При использовании формы A выражение c ? x : y вызовет ошибку компиляции с clang 11.

Хуже того, gcc 10 просто молча притворится, что ext_vector_type(N) имеет 4 элемента, даже если N равно 8 или 16.

При использовании формы B выражение c ? x : y должным образом переведено в векторное сочетание с помощью clang 11. Clang 10 и Хотя gcc 10 переводит его во что-то другое, но они оба могут его скомпилировать.

Мне непонятно, зачем существует форма ext_vector_type, особенно учитывая, как плохо она работает.

ОБНОВЛЕНИЕ Тьфу... это работает только в C++, но не в C. ПОЧЕМУ???

person Bram    schedule 27.11.2020
comment
ext_vector_type изначально был лязгом, я не знал, что GCC его вообще поддерживает. Я не знаю, для чего это было, однако, что вы уже не могли сделать с vector_size - person Peter Cordes; 27.11.2020
comment
@PeterCordes Какой беспорядок ... Я обнаружил, что это работает только на C ++, а не на C. Тьфу ... тогда вернемся к внутренним свойствам. - person Bram; 04.05.2021