Язык ассемблера и скомпилированные языки
Как сборка быстрее, чем скомпилированные языки, если оба они переведены в машинный код?
Я говорю о действительно скомпилированных языках, которые переводятся в машинный код. Не на C# или Java, которые сначала компилируются на промежуточный язык, а затем компилируются в собственный код программным интерпретатором и т. Д.
В Википедии я нашел что-то, в чем я не уверен, связано ли это как-то с этим. Это потому, что перевод с языка более высокого уровня генерирует дополнительный машинный код? Или мое понимание неверно?
Утилита, называемая ассемблером, используется для перевода операторов ассемблера в машинный код целевого компьютера. Ассемблер выполняет более или менее изоморфное преобразование (взаимно-однозначное отображение) из мнемонических операторов в машинные инструкции и данные. Это отличается от языков высокого уровня, в которых одно утверждение обычно приводит к множеству машинных инструкций.
8 ответов
Ну, это действительно имеет отношение к вашему вопросу. Дело в том, что компиляторы время от времени производят неэффективный машинный код по разным причинам, например, из-за невозможности полного анализа вашего кода, вставки автоматических проверок диапазона, автоматических проверок объектов, null
, так далее.
С другой стороны, если вы пишете код на ассемблере от руки и знаете, что делаете, то вы, вероятно, можете написать некоторые вещи, гораздо более эффективные, чем компилятор, хотя поведение компилятора может быть изменено, и вы обычно можете сказать ему не выполнять диапазон проверка, например.
Однако большинство людей не будут писать лучший ассемблерный код, чем компилятор, просто потому, что компиляторы написаны людьми, которые знают много действительно странных, но действительно крутых оптимизаций. Кроме того, такие вещи, как развертывание цикла, обычно являются трудной задачей для себя, и во многих случаях ускорение получающегося кода ускоряется.
Хотя обычно верно, что все, что выполняет компьютер, является машинным кодом, код, который выполняется, сильно отличается в зависимости от того, сколько уровней абстракции вы поместили между машиной и программистом. Для Ассемблера это один уровень, для Java есть еще несколько...
Также многие люди ошибочно полагают, что определенные оптимизации на более высоком уровне абстракции окупаются на более низком. Это не обязательно так, и у компилятора могут возникнуть проблемы с пониманием того, что вы пытаетесь сделать, и он не может должным образом оптимизировать его.
Сборка иногда может быть быстрее, чем скомпилированный язык, если программист на ассемблере пишет лучшую сборку, чем сгенерированная компилятором.
Скомпилированный язык часто быстрее ассемблера, потому что программисты, которые пишут компиляторы, обычно знают архитектуру процессора лучше, чем обычные программисты.
Эксперт по сборке может написать более эффективный код сборки (меньше инструкций, более эффективные инструкции, SIMD, ...), чем тот, который компилятор генерирует автоматически.
Тем не менее, в большинстве случаев вам лучше доверять оптимизатору вашего компилятора.
Узнайте, что делает ваш компилятор. Тогда пусть компилятор сделает это.
Все хорошие ответы. Мое единственное дополнительное замечание - программисты, как правило, пишут определенное количество строк кода в день, независимо от языка. Поскольку преимущество языка высокого уровня заключается в том, что он позволяет выполнять больше работы с меньшим количеством кода, требуется невероятная дисциплина программиста, чтобы фактически писать меньше кода.
Это особенно важно для производительности, потому что это практически не имеет значения, за исключением крошечной части кода. Это имеет значение только в ваших горячих точках - код, который вы пишете (1), потребляет значительную долю времени выполнения (2) без вызова функций (3).
Мой стандартный ответ, когда возникают вопросы о сборке и высоком уровне, - взглянуть на " Черную книгу" по программированию Майкла Абраша.
Первая пара глав дает хорошее представление о том, что вы можете эффективно оптимизировать с помощью сборки, а что нет.
Вы можете скачать его с GameDev - ссылки Джеффа сейчас, к сожалению, не работают.
Как сборка быстрее, чем скомпилированные языки, если оба они переведены в машинный код?
Неявное предположение - рукописный ассемблерный код. Конечно, большинство компиляторов (например, GCC для C, C++, Fortran, Go, D и т. Д.) Генерируют некоторый ассемблерный код; например, вы можете скомпилировать foo.cc
Исходный код C++ с g++ -fverbose-asm -Wall -S -O2 -march=native foo.cc
и посмотреть в сгенерированный foo.s
ассемблерный код.
Однако, написать эффективный ассемблерный код так сложно, что сегодня компиляторы могут оптимизировать его лучше, чем это делает человек. Смотрите это.
С практической точки зрения, кодирование на ассемблере не стоит (также следует учитывать, что усилия по разработке очень часто стоят намного дороже, чем аппаратное обеспечение, на котором выполняется скомпилированный код). Даже когда производительность имеет большое значение и стоит потратить много денег, лучше вручную написать лишь несколько подпрограмм на ассемблере или даже встроить некоторый код на ассемблере в некоторые из ваших подпрограмм на Си.
Посмотрите доклад CppCon 2017: Мэтт Годболт: "Что мой компилятор сделал для меня в последнее время? Откручиваем крышку компилятора "
Прежде всего, компиляторы генерируют очень хороший (быстрый) код сборки.
Это правда, что компиляторы могут добавлять дополнительный код, поскольку языки высокого порядка имеют механизмы, такие как виртуальные методы и исключения в C++. Таким образом, компилятор должен будет генерировать больше кода. Бывают случаи, когда необработанная сборка может ускорить код, но в наше время это происходит редко.
Во-первых, ассемблер должен использоваться только в небольших кусках кода, которые занимают большую часть процессорного времени в программе - например, какие-то вычисления - в "узком месте" алгоритма.
Во-вторых - это зависит от опыта в ASM тех, кто реализует тот же код в Assembler. Если на ассемблере реализация "бутылочного горлышка" кода будет быстрее. Если опыта мало - будет медленнее. И это будет содержать много ошибок. Если опыт достаточно высок - ASM даст значительную прибыль.