Испускают ли компиляторы обычно векторные (SIMD) инструкции, когда не говорят об этом явно?

C ++ 17 добавляет расширения для параллелизма в стандартную библиотеку (например, std::sort(std::execution::par_unseq, arr, arr + 1000), что позволяет выполнять сортировку с использованием нескольких потоков и векторных инструкций).

Я заметил, что в экспериментальной реализации Microsoft упоминается, что компилятор VC ++ не поддерживает векторизацию здесь, что меня удивляет - я думал, что современные компиляторы C ++ могут рассуждать о векторизуемости циклов, но, очевидно, компилятор / оптимизатор VC ++ не может сгенерировать код SIMD, даже если это явно сказано. Кажущееся отсутствие поддержки автоматической векторизации противоречит ответам на этот вопрос 2011 г. на Quora, в котором предполагается, что компиляторы будут выполнять векторизацию там, где это возможно.

Возможно, компиляторы будут векторизовать только очень очевидные случаи, такие как std::array<int, 4>, и не более того, поэтому явное распараллеливание C ++ 17 будет полезно.

Отсюда мой вопрос: автоматически ли текущие компиляторы векторизуют мой код, если об этом не сказано явно? (Чтобы сделать этот вопрос более конкретным, давайте сузим его до процессоров Intel x86 с поддержкой SIMD и последних версий GCC, Clang, MSVC и ICC.)

В качестве расширения: улучшают ли компиляторы для других языков автоматическую векторизацию (возможно, из-за дизайна языка) (чтобы комитет по стандартам C ++ решил, что это необходимо для явной (в стиле C ++ 17) векторизации)?


person Bernard    schedule 03.06.2017    source источник
comment
Как обычно, это зависит от компилятора, а это означает, что сейчас единственный возможный ответ - «возможно». Запросите конкретный компилятор. Кроме того, стандарт никогда не будет указывать какую-либо векторизацию или оптимизацию вообще - C ++ работает на многих различных архитектурах, некоторые из которых не поддерживают векторные инструкции или определенные операции. Все, что связано с оптимизацией, определяется реализацией.   -  person tambre    schedule 03.06.2017
comment
@tambre Я изменил вопрос, чтобы отразить, что я сосредотачиваюсь на четырех современных компиляторах C ++. Я знаю, что стандарт вообще никогда не будет определять векторизацию; Я думал, что мой вопрос подразумевает, что меня интересует только оборудование, которое имеет необходимые векторные инструкции SIMD. Тем не менее, прямо сейчас заявили об этом.   -  person Bernard    schedule 03.06.2017
comment
Ничто в вашей ссылке ничего не говорит о том, что VC ++ не может отправлять инструкции SIMD. Кроме того, последняя редакция отредактирована 17 апреля 2014 г. в 00:17.   -  person user2357112 supports Monica    schedule 03.06.2017
comment
На этой странице говорится только о том, что эта конкретная экспериментальная реализация экспериментальной библиотеки не делает ничего особенного, когда ей говорят, что она может векторизовать выполнение. Он ничего не говорит о том, будет ли компилятор все равно векторизовать его, или может ли компилятор автовекторизовать другой код.   -  person user2357112 supports Monica    schedule 03.06.2017
comment
Вы знаете, я никогда особо не использовал VC, так как я а) понял, что некоторые узкие места в GCC на 300% быстрее, ничего не меняя, б) надоело множество несовместимостей со стандартом. ... Не удивляйтесь, если VC не самый быстрый и / или не имеет функций. Это нормально. (И не заставляйте меня начинать с std lib. Mutex: o)   -  person deviantfan    schedule 03.06.2017
comment
@deviantfan А когда вы в последний раз пользовались ВК? Насколько я понимаю, они находятся в процессе полной замены всего своего интерфейса.   -  person tambre    schedule 03.06.2017
comment
@tambre Я явно не про UI.   -  person deviantfan    schedule 03.06.2017
comment
@deviantfan Я тоже не говорил о графическом интерфейсе. Я имел в виду фронтенд компилятора. Я думал, это было бы достаточно ясно из контекста.   -  person tambre    schedule 03.06.2017
comment
@tambre Хотя я знал, что соответствие стандарту постепенно улучшается; план серьезной модернизации интерфейса действительно для меня новость; спасибо (только что прочитал статью за 2015 год) .... (Однако проблемы с производительностью и stdlib все еще существуют. Опять же, пользователи VS, не слишком удивляйтесь)   -  person deviantfan    schedule 03.06.2017
comment
всякий раз, когда есть возможность, это крайнее преувеличение, превращающее компилятор в своего рода всемогущего бога - реальность, если, конечно, всякий раз, когда компилятор способен обнаружить и использовать эту возможность. Есть много векторных шаблонов, которые компиляторы не реализуют.   -  person harold    schedule 03.06.2017
comment
@ user2357112 Сказать, что VC ++ не может сгенерировать SIMD-код, когда это явно сказано, было преувеличением. Я понял. В настоящее время мы работаем над поддержкой компилятора, чтобы правильно реализовать политику std::vec, что означает, что компилятор (в отличие от библиотеки) не имеет надлежащей поддержки векторизации в целом. Тогда полезность явного распараллеливания C ++ 17 будет связана с тем, что компилятор не может распознать определенные векторизуемые шаблоны, или из-за того, что внешняя информация недоступна для компилятора.   -  person Bernard    schedule 03.06.2017
comment
VC ++ может генерировать векторизованные инструкции. Эти библиотечные функции не будут.   -  person Yakk - Adam Nevraumont    schedule 04.06.2017
comment
Конечно, MSVC генерирует векторные инструкции, но он очень плохо справляется с автоматической векторизацией. Другие компиляторы (GCC, Clang и ICC) работают лучше, но они все еще не идеальны.   -  person Cody Gray    schedule 04.06.2017
comment
Godbolt поддерживает Clang, GCC, ICC и MSVC. Посмотрите на сборку, чтобы проверить векторизацию. Все эти компиляторы могут векторизоваться в зависимости от кода godbolt.org/g/DB4rYO   -  person Z boson    schedule 06.06.2017


Ответы (1)


Лучший компилятор для автоматического определения векторизации в стиле SIMD (когда ему говорят, что он, конечно, может генерировать коды операций для соответствующих наборов инструкций), по моему опыту, является компилятор Intel (который может генерировать код для динамической отправки в зависимости от фактического процессора, если это необходимо), близко за ним следуют GCC и Clang, а MSVC - последний (из ваших четырех).

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

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

Это, я думаю, указывает на проблему с надеждой, что компилятор (для C ++ или другого языка) выполнит всю работу по векторизации ... если у вас есть простые циклы векторной обработки (например, умножение всех элементов в векторе на скаляр) тогда да, можно было ожидать, что 3 из 4 компиляторов это заметят.

Но для более сложного кода выигрыш от векторизации, который может быть достигнут не за счет простого разворачивания цикла и объединения итераций, а за счет фактического использования другого или измененного алгоритма, и компилятору будет сложно, если вообще возможно, сделать это в одиночку. Если вы понимаете, как векторизация может быть применена к алгоритму, и можете структурировать свой код, чтобы компилятор мог видеть возможности для этого, возможно, с конструкциями pragma simd или OpenMP, тогда вы можете получить желаемые результаты.

Векторизация происходит, когда код имеет определенную механическую симпатию к базовому процессору и шине памяти - если это у вас есть, то я думаю, что компилятор Intel будет вашим лучшим выбором. Без него смена компилятора мало что изменит.

Могу ли я порекомендовать Compiler Explorer Мэтта Годболта как способ проверить это - поместите туда свой код C ++ и посмотрите, что еще компиляторы на самом деле генерируют? Очень удобно ... он не включает старую версию MSVC (я думаю, что в настоящее время он поддерживает VC ++ 2017 и более поздние версии), но покажет вам, что разные версии ICC, GCC, Clang и другие могут делать с кодом ...

person Tim    schedule 04.06.2017
comment
Обозреватель компилятора Godbolt действительно включает MSVC. Так не было с самого начала, но так происходит сейчас, и так уже несколько месяцев. - person Cody Gray; 04.06.2017
comment
Привет, Коди ... Боже мой, да, Оптимизирующий компилятор Microsoft (R) C / C ++ версии 19.10.25017 доступен как x86 CL 19 2017 RTW (я ожидал чего-то более похожего на MSVC в качестве ярлыка), спасибо за предупреждение. - person Tim; 04.06.2017
comment
Спасибо, что указали на обозреватель компилятора Godbolt, я обязательно его проверю! - person Bernard; 04.06.2017
comment
@Tim не могли бы вы отредактировать свой ответ, чтобы отразить уровень поддержки MSVC в MSVC? - person olq_plo; 19.01.2019