Когда сборка происходит быстрее, чем C? - PullRequest
440 голосов
/ 23 февраля 2009

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

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

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

Ответы [ 39 ]

4 голосов
/ 08 февраля 2014

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

4 голосов
/ 17 сентября 2010

Longpoke, есть только одно ограничение: время. Если у вас нет ресурсов для оптимизации каждого отдельного изменения в коде и вы тратите свое время на выделение регистров, оптимизацию нескольких разливов и что нет, компилятор будет побеждать каждый раз. Вы вносите свои изменения в код, перекомпилируете и измеряете. Повторите при необходимости.

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

int y = data [i]; // сделать что-то здесь .. call_function (y, ...);

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

// оптимизированная версия call_function (data [i], ...); // все-таки не так оптимизировано ..

Идея с оптимизированной версией заключалась в том, что мы уменьшили давление в регистре и избежали пролива. Но на самом деле «дерьмовая» версия оказалась быстрее!

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

Здесь следует обратить внимание: многие эксперты по сборке думают , что они знают много, но знают очень мало. Правила меняются от архитектуры к следующей тоже. Например, не существует x86-кода «серебряная пуля», который всегда самый быстрый. В эти дни лучше идти по эмпирическим правилам:

  • память медленная
  • кеш быстрый
  • попробуй лучше использовать кэшированный
  • как часто ты будешь скучать? у вас есть стратегия компенсации задержки?
  • вы можете выполнить 10-100 ALU / FPU / SSE инструкций для одного промаха одного кеша
  • важна архитектура приложения ..
  • .. но это не помогает, когда проблема не в архитектуре

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

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

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

Все сводится к следующему: «понимать, что ты делаешь», это немного отличается от знания, что ты делаешь.

1 голос
/ 23 февраля 2009

На этот вопрос очень сложно ответить конкретно, потому что вопрос очень неопределенный: что такое «современный компилятор»?

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

1 голос
/ 19 августа 2014

На самом деле вы можете создавать крупномасштабные программы в режиме большой модели. Сегменты могут быть ограничены кодом 64 КБ, но вы можете написать много сегментов, люди приводят аргументы против ASM, поскольку это старый язык, и нам не нужно сохранять память больше, если бы это было так, почему мы собирали наши ПК с памятью, единственный недостаток, который я могу найти с ASM, - это то, что он более или менее основан на процессорах, поэтому большинство программ, написанных для архитектуры Intel, скорее всего, не будут работать на AMD Архитектура. Что касается того, что C быстрее, чем ASM, то нет более быстрого языка, чем ASM, и ASM может многое делать на C, а другие HLL не могут делать на уровне процессора. ASM - сложный язык для изучения, но как только вы выучите его, никакой HLL не сможет перевести его лучше, чем вы. Если бы вы только увидели, что HLL делает с вами, и поняли, что он делает, вы бы удивились, почему все больше людей не используют ASM и почему сборки больше не обновляются (в любом случае, для общего пользования). Так что ни один C не быстрее, чем ASM. Даже опытные программисты на C ++ все еще используют и пишут код Chunks в ASM, добавленный туда для ускорения кода C ++. Другие языки Также то, что некоторые люди считают устаревшими или, возможно, бесполезными, порой является мифом, например, Photoshop написан на языке Pascal / ASM. 1-й выпуск souce был представлен в музей технической истории, а painttshop pro написан на языке Python, TCL и ASM ... общим знаменателем этих терминов для "Быстрых и великолепных процессоров изображений" является ASM, хотя Photoshop, возможно, обновился до Delphi, теперь он все еще паскаль. И любые проблемы со скоростью возникают из паскаля, но это потому, что нам нравится способ программы выглядят, а не то, что они делают в наши дни. Я хотел бы сделать клон Photoshop в чистом ASM, над которым я работаю, и он довольно хорошо работает, а не кодировать, интерпретировать, разбирать, переписывать и т. д. Просто код и идти процесс завершен.

1 голос
/ 24 февраля 2009

В дни, когда скорость процессора измерялась в МГц, а размер экрана был ниже 1 мегапикселя, общеизвестным трюком для быстрого отображения было развертывание циклов: операция записи для каждой строки сканирования экрана. Это позволило избежать накладных расходов на поддержание индекса цикла! В сочетании с обнаружением обновления экрана это было довольно эффективно.
Это то, что компилятор C не будет делать ... (хотя часто вы можете выбирать между оптимизацией по скорости или по размеру, я полагаю, что первый использует некоторые похожие приемы.)

Я знаю, что некоторым людям нравится писать приложения для Windows на ассемблере. Они утверждают, что они быстрее (трудно доказать) и меньше (действительно!).
Очевидно, что в то время как это интересно, вероятно, это потраченное впустую время (за исключением цели обучения, конечно!), Особенно для операций с графическим интерфейсом ... Теперь, возможно, некоторые операции, такие как поиск строки в файле, можно оптимизировать с помощью тщательно написанного кода сборки.

0 голосов
/ 13 мая 2019

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

0 голосов
/ 23 февраля 2009

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

0 голосов
/ 16 апреля 2011

В настоящее время, учитывая такие компиляторы, как Intel C ++, которые чрезвычайно оптимизируют код C, очень трудно конкурировать с выходом компиляторов.

0 голосов
/ 03 марта 2009

Раньше я работал с кем-то, кто говорил: «Если компилятор не может понять, что вы пытаетесь сделать и не можете его оптимизировать, ваш компилятор сломан, и пришло время получить новый». Я уверен, что есть крайние случаи, когда ассемблер побьет ваш C-код, но если вам часто приходится использовать ассемблер, чтобы «победить» ваш компилятор, ваш компилятор сломается.

То же самое можно сказать и о написании «оптимизированного» SQL, который пытается заставить планировщик запросов выполнять какие-либо действия. Если вы обнаружите, что реорганизуете запросы, чтобы планировщик выполнял то, что вам нужно, ваш планировщик запросов отключился - получите новый.

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