GCC самый высокий набор инструкций, совместимый с несколькими архитектурами - PullRequest
0 голосов
/ 28 июня 2018

Я выполняю задания в кластере, состоящем из машин с различной архитектурой: gcc -march=native -Q --help=target | grep -- '-march=' | cut -f3 дает мне один из них: broadwell, haswell, ivybridge, sandybridge или skylake.

Исполняемый файл должен быть таким же, поэтому я не могу использовать -march=native, но в то же время у архитектур есть общие черты (я думаю, что они все поддерживают AVX?).

Мне известно, что gcc (в отличие от Intel icc) не допускает наличие нескольких архивных изображений в одном исполняемом файле. Я хотел бы знать, есть ли способ запросить у gcc самый высокий набор инструкций, совместимый со всеми перечисленными выше архитектурами.

Версия gcc: 8.1.1

Ответы [ 3 ]

0 голосов
/ 28 июня 2018

Комментарии предложили мне взглянуть на «пересечение» между архитектурами. Кажется, следующий скрипт bash делает эту работу.

#!/usr/bin/env bash

archs=("broadwell" "haswell" "ivybridge" "sandybridge" "skylake")

for ar in ${archs[@]}; do
    gcc -march=$ar -Q --help=target | grep -- "  -m" > "$ar.log"
done

cp "${archs[0]}.log" all.log
for ar in ${archs[@]:1}; do
    join all.log "$ar.log" > tmp.log
    mv tmp.log all.log
done

cat all.log | grep "\[activé]" | grep -v "\[désactivé]" | cut -d' ' -f1 | tr '\n' ' '

(Компьютер на французском языке: "activé" => "включено", "désactivé" => "отключено")

Выход

-m128bit-long-double -m64 -m80387 -maes -malign-stringops -mavx -mcx16 -mfancy-math-387 -mfp-ret-in-387 -mfxsr -mglibc -mhard-float -mieee-fp -mlong-double-80 -mmmx -mpclmul -mpopcnt -mpush-args -mred-zone -msahf -msse -msse2 -msse3 -msse4 -msse4.1 -msse4.2 -mssse3 -mstv -mtls-direct-seg-refs -mvzeroupper -mxsave -mxsaveopt

Как и ожидалось, все архитектуры поддерживают SSE и AVX.

0 голосов
/ 28 июня 2018

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

(Единственное исключение - это Xeon Phi первого поколения: Knight's Corner использовал несовместимый вариант AVX512 под названием KNI, но в более поздних ускорительных картах / компьютерах Xeon Phi используется AVX512.)


Если вы должны использовать один и тот же двоичный файл на всех процессорах, используйте gcc -march=sandybridge -mtune=haswell и убедитесь, что ваши важные массивы выровнены по 32 байта.

Возможно, стоит сравнить с gcc -march=sandybridge (то есть с tune = sandybridge), чтобы увидеть, какой из них лучше работает для вашего кода. -mprefer-avx128 или -mprefer-vector-width=256 может быть интересно попробовать: некоторые циклы запутываются, когда gcc автоматически векторизуется с 256-битными векторами.


SnB / IvB имеют неэффективные неверно выровненные загрузки / хранилища AVX, поэтому tune = sandybridge устанавливает -mavx256-split-unaligned-load, что очень много, если ваши данные выровнены во время выполнения, но компилятор этого не знал. Дополнительные инструкции и тасования не помогают в Haswell, поэтому -mtune=haswell включает -mno-avx256-split-unaligned-load.

К сожалению, у gcc нет опции "tune = avx2" для настройки всех процессоров, у которых есть AVX2, или опции для настройки среднего процессора, которая поддерживает наборы инструкций, которые вы включили. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80568. Ваши единственные варианты: настройка для конкретного ЦП, или настройка на базовую базовую линию, или использование определенных параметров настройки.


Gcc имеет некоторую поддержку для диспетчеризации во время выполнения с ifunc

Вы должны активировать его в источнике для определенных функций. См. https://lwn.net/Articles/691932/ для получения дополнительной информации о функции многократного управления версиями.


Лучший вариант: создать отдельные двоичные файлы для SnB / Haswell и отправить с помощью скрипта или $PATH с настройкой

На каждом узле кластера создайте /etc/host-type или что-то еще, которое имеет sandybridge или haswell или что-то еще. Любая файловая система для каждого узла в порядке, или повторно обнаружите ее во время выполнения с gcc или чем-то более дешевым. В вашем рабочем скрипте:

#!/bin/sh

bin_dir="./bin-$(</etc/node-type)"
exec "$bin_dir/my_prog"  "$@"

При необходимости создайте символические ссылки, чтобы bin-skylake и bin-broadwell использовали двоичные файлы Haswell.

Haswell представила AVX2 и FMA, а также BMI1 / 2. Если вам не хватает числа, вы действительно хотите FMA . BDW / SKL не представил каких-либо существенных расширений ISA, которые компиляторы могут использовать для ускорения работы вашего кода. Настройка для BDW / SKL также не отличается.

Если у вас есть какие-либо процессоры Skylake-avx512, это не так.

0 голосов
/ 28 июня 2018

Я хотел бы знать, есть ли способ запросить у gcc наивысший набор инструкций, совместимый со всеми перечисленными выше архитектурами.

Это НЕТ.

Если вы хотите оптимальной производительности, посмотрите на двоичные файлы, как прокомментировал Санер Де Дайкер.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...