Смешивание ассемблерного кода с c / c ++ - PullRequest
6 голосов
/ 04 сентября 2010

Почему код на ассемблере часто требуется вместе с C / C ++?

Что нельзя сделать в C / C ++, что возможно при смешанном коде на ассемблере?

У меня есть некоторый исходный код некоторых 3D компьютерных игр. Используется много ассемблерного кода.

Ответы [ 8 ]

14 голосов
/ 04 сентября 2010

Вещи, которые приходят на ум, в произвольном порядке:

  • Специальные инструкции.Во встроенном приложении мне нужно аннулировать кэш после того, как передача DMA заполнила буфер памяти.Единственный способ сделать это на процессоре SH-4 - выполнить специальную инструкцию, поэтому единственный способ - это встроенная сборка (или функция автономной сборки).

  • Оптимизации.Когда-то давно для компиляторов было свойственно не знать каждый трюк, который можно было сделать.В некоторых из этих случаев стоило усилий заменить внутреннюю петлю версией, сделанной вручную.Что касается типов процессоров, которые вы найдете в небольших встраиваемых системах (например, 8051, PIC и т. Д.), Полезно вставить внутренние контуры в сборку.Подчеркну, что для современных процессоров с конвейерами, многозадачным выполнением, обширным кэшированием и т. Д. Ручному кодированию зачастую крайне сложно даже приблизиться к возможностям оптимизатора.

  • Обработка прерываний.Во встроенном приложении часто требуется перехватывать системные события, такие как прерывания и исключения.Часто бывает так, что первые несколько инструкций, выполняемых прерыванием, имеют особые обязанности, и единственный способ гарантировать, что правильные вещи произойдут, - написать внешний слой обработчика в сборке.Например, на ColdFire (или любом потомке 68000) гарантированно будет выполняться только самая первая инструкция.Чтобы предотвратить вложенные прерывания, эта инструкция должна изменить уровень приоритета прерывания, чтобы замаскировать приоритет текущего прерывания.

  • Определенные части ядра ОС.Например, переключение задач требует, чтобы состояние выполнения (по крайней мере, большинство регистров, включая ПК и указатель стека) было сохранено для текущей задачи, а состояние загружено для новой задачи.Работа с состоянием выполнения ЦП находится далеко за пределами набора функций языка, но может быть заключена в небольшое количество ассемблерного кода таким образом, чтобы остальная часть ядра могла быть написана на C или C ++.

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

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

3 голосов
/ 04 сентября 2010

Есть определенные вещи, которые можно сделать только на ассемблере, но нельзя сделать на C / C ++.

К ним относятся:

  1. генерация программных прерываний (инструкции SWI или INT)
  2. Использование инструкций типа SWP для создания мьютексов
  3. инструкции специального сопроцессора (например, необходимые для программирования MMU и управления кэш-памятью RAM)
  4. Доступ к флагам переноса и переполнения.

Вы также можете оптимизировать код на ассемблере лучше, чем на C / C ++ (например, memcpy на Android написан на ассемблере)

3 голосов
/ 04 сентября 2010

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

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

2 голосов
/ 04 сентября 2010

Почему код ассемблера часто нужен вместе с C / C ++?

Конкурентное преимущество. Например, если вы пишете программное обеспечение для (в ближайшее время) игровой компании № 1 в мире.

Что нельзя сделать в C / C ++, что возможно при коде ассемблера смешано?

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

Редактировать: судя по другим ответам, похоже, что все встраиваемые системы (iPhone, Android и т. Д.) Имеют аппаратные ускорители, которые, безусловно, требуют использования сборки.

У меня есть некоторый исходный код какой-то 3D компьютерные игры. Есть много Используется ассемблерный код.

Они либо написаны в 80-х-90-х годах, либо используются редко (возможно, 1% - 5% от общего исходного кода) внутри игрового движка.

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

Обновление:

Согласно неподтвержденным данным, RollerCoaster Tycoon написан на 99% сборке.
http://www.chrissawyergames.com/faq3.htm

2 голосов
/ 04 сентября 2010

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

1 голос
/ 05 сентября 2010

Еще одна вещь, о которой стоит упомянуть:

  • C & C ++ не предоставляют какого-либо удобного способа настройки стековых фреймов, когда нужно реализовать взаимодействие на двоичном уровне с языком сценариев или реализовать некоторыевид поддержки для замыканий.
1 голос
/ 04 сентября 2010

Почему код ассемблера часто нужен вместе с C / C ++? нужен вместе с C / C ++?

Это не

Что нельзя сделать в C / C ++, что возможно при коде ассемблера смешано?

Доступ к системным регистрам или портам ввода-вывода на ЦПУ. Доступ к функциям BIOS. Используя специализированные инструкции, которые не отображаются непосредственно на язык программирования, например SIMD инструкция. Предоставьте оптимизированный код, который лучше, чем производит компилятор.

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

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

0 голосов
/ 04 сентября 2010

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

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