Почему -march = native используется так редко? - PullRequest
0 голосов
/ 04 октября 2018

У большинства компиляторов C / C ++ есть флаг, передаваемый компилятору -march=native, который указывает компилятору настраивать сгенерированный код для микроархитектуры и расширений ISA центрального процессора.Даже если имя не совпадает, обычно для компиляторов на основе LLVM существует эквивалентная опция, например rustc или swiftc.

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

  • Очевидно, что любой исполняемый файл компилятора командной строки, который требует, чтобы вы передали егоне использует его по умолчанию.

  • Я не могу представить ни одну IDE, которая бы включала это по умолчанию.

  • Не могуВспомните любую обычную систему сборки, с которой я работал (cmake, automake, cargo, spm и т. д.), которая включает ее по умолчанию даже для оптимизированных сборок.

Я могу придумать несколько причин для этого, но ни одна из них не является действительно удовлетворительной:

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

  • По крайней мере, на процессорах Intel x86, насколько я понимаю, использование инструкций AVX нечасто может привести к снижению производительности или эффективности энергопотребления, поскольку блок AVX отключается, когда он не используется, что требует его включения для использования, и большое количествоРазгон процессоров Intel для запуска инструкций AVX.Тем не менее, это только объясняет, почему AVX не будет включен, а не то, почему код не будет настроен для конкретной микроархитектуры для обработки обычных инструкций.

  • Поскольку большинство процессоров x86 используютНеобычные суперскалярные конвейеры с переименованием регистров, настройка кода для конкретной микроархитектуры, вероятно, не особенно важна.Тем не менее, если может помочь, почему бы не использовать его?

Ответы [ 3 ]

0 голосов
/ 05 октября 2018

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

У большинства разработчиков есть отдельная машина разработки и целевые производственные системы.В случае потребительских приложений эта целевая система является машиной других людей со всеми отклонениями.Сборка для наиболее распространенного знаменателя является безопасным по умолчанию, поскольку она уменьшает вероятность ошибок, возникающих только за пределами собственных машин разработчика.

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

0 голосов
/ 05 октября 2018

Консервативный

Если вы присмотритесь к значениям по умолчанию gcc, самого старого компилятора в вашем списке, вы поймете, что они очень консервативны:

  • По умолчаниюна x86 активирован только SSE 2;даже не SSE 4.
  • Набор флагов в -Wall и -Wextra не менялся годами;Есть новые полезные предупреждения, они НЕ добавляются в -Wall или -Wextra.

Почему?Потому что это сломало бы вещи!

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

Чем больше пользователей, тем больше угроза, поэтому разработчики gcc очень и очень консервативны, чтобы избежать поломок по всему миру.И разработчики следующей партии компиляторов идут по стопам своих старших: доказано, что это работает.

Примечание: rustc по умолчанию будет использовать статическое связывание и может похвастаться тем, что вы можете просто скопировать двоичный файли бросить его на другую машину;очевидно, что -march=native будет препятствием там.

MASS Friendly

И, по правде говоря, это, вероятно, не имеет значения.Вы действительно узнали это сами:

По моему опыту, этот флаг может обеспечить значительное ускорение для числового кода

Большая часть кода заполнена виртуальными вызовами и ветвями (как правило, код ОО), а не числовой.Таким образом, для большей части кода часто достаточно SSE 2.

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

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

Заключение

Не активировать -march=native с помощьюнастройка по умолчанию облегчает пользователям начало работы;поскольку даже те, кто ищет производительность, могут не заботиться об этом больше, это означает, что можно потерять больше, чем выиграть.


В альтернативной истории, где значением по умолчанию было -march=native с самого начала;пользователи будут использоваться для определения целевой архитектуры, и у нас не будет этого обсуждения.

0 голосов
/ 05 октября 2018

-march=native - разрушительный флаг.Это делает двоичный код несовместимым на большом количестве аппаратного обеспечения (в основном, на любом процессоре, который не является прямым потомком того, который использовался для компиляции).Просто слишком опасно включать это по умолчанию.

Еще одна важная вещь, которую следует учитывать, - это то, что основным конечным применением -march=native является оптимизация.Флаг оптимизации по умолчанию - -O0 (без оптимизации), поэтому с этой точки зрения не имеет смысла включать его по умолчанию.

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