Язык ассемблера и скомпилированные языки

Как сборка быстрее, чем скомпилированные языки, если оба они переведены в машинный код?

Я говорю о действительно скомпилированных языках, которые переведены на машинный код. Не С# или Java, которые сначала скомпилированы на промежуточный язык, а затем скомпилированы в собственный код с помощью программного интерпретатора и т.д.

В Wikipedia я нашел что-то, что я не уверен, если оно каким-либо образом связано с этим. Это потому, что перевод с языка более высокого уровня создает дополнительный машинный код? Или мое понимание не так?

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

Ответ 1

Ну, это немного относится к вашему вопросу. Дело в том, что компиляторы иногда производят неэффективный машинный код по разным причинам, например, не могут полностью анализировать ваш код, вставлять автоматические проверки диапазона, автоматические проверки объектов null и т.д.

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

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

Хотя в целом верно, что все, что компьютер выполняет, это машинный код, код, который работает, сильно отличается в зависимости от того, сколько уровней абстракции вы ставите между машиной и программистом. Для Ассемблера на одном уровне для Java есть еще несколько...

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

Ответ 2

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

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

Ответ 3

Специалист по сборке может написать более эффективный код сборки (меньшее количество инструкций, более эффективных инструкций, SIMD,...), чем то, что автоматически генерирует компилятор.

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

Узнайте, что делает ваш компилятор. Тогда пусть компилятор сделает это.

Ответ 4

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

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

Вы можете загрузить его из GameDev - ссылки Джеффа, похоже, сейчас сломаны.

Ответ 5

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

Это особенно важно для производительности, потому что это имеет значение почти нигде, кроме как в крошечной части кода. Это важно только в ваших горячих точках - код, который вы пишете (1), потребляющий значительную часть времени выполнения (2) без вызова функций (3).

Ответ 6

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

Во-вторых - это зависит от опыта в ASM тех, кто реализует один и тот же код в Assembler. Если реализация ассемблера кода "бутылочной горловины" будет быстрее. Если опыт низкий - он будет медленнее. И в нем будет много ошибок. Если опыт достаточно высок - ASM даст значительную прибыль.

Ответ 7

Прежде всего, компиляторы генерируют очень хороший (быстрый) код сборки.

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

Ответ 8

Как сборка быстрее, чем скомпилированные языки, если оба они переведены в машинный код?

Неявное предположение представляет собой рукописный ассемблерный код. Конечно, большинство компиляторов (например, GCC для C, С++, Fortran, Go, D и т.д.) Генерируют некоторый код ассемблера; например, вы можете скомпилировать исходный код foo.cc С++ с помощью g++ -fverbose-asm -Wall -S -O2 -march=native foo.cc и посмотреть в сгенерированный код ассемблера foo.s.

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

Практически говоря, не стоит кодирования в ассемблере (также учтите, что усилия по разработке стоят очень часто намного больше, чем аппаратное обеспечение, выполняющее скомпилированный код). Даже когда производительность имеет большое значение и стоит потратить много денег, лучше всего вручную обработать только несколько процедур в ассемблере или даже внедрить некоторые ассемблер в некоторых ваших подпрограммах C.

Посмотрите на разговор CppCon 2017: Matt Godbolt "Что мой компилятор для меня сделал в последнее время? Отпирание крышки компилятора"