Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: К вопросу об оптимизации инлайн-ассемблера.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
AHTOXA
Я много раз читал, что инлайн-ассемблер в gcc замечательно оптимизируется. Да и глядя в дизассемблер, убеждался, что это так и есть. Но недавно наткнулся на материал про встроенные функции GCC, и решил их испытать.
Заменил на пробу
Код
INLINE inline byte GetHighPriority(TProcessMap pm)
  {
      dword clzero;
      asm ("clz\t%0, %1": "=r" (clzero): "r" (pm));
      return (31 - clzero);
}

на
Код
INLINE inline byte GetHighPriority(TProcessMap pm)
    {
        return (31 - __builtin_clz(pm));
    }

Собственно код, генерируемый компилятором для этой функции - не поменялся. Но. Размер проекта уменьшился на 40 байт. Это для пяти вызовов данной функции. Это конечно мелочи для проекта на 16 Кб, но тем не менее. Насколько я понял по листингу, при использовании __builtin_clz() компилятор несколько более оптимально перетасовывает окружающие куски кода.
Собственно, вывод мой таков - несмотря на отличную оптимизацию встроенного ассемблера, компилятор не может (или не хочет) применять к нему все возможные методы оптимизации. Возможно, этот вывод поспешен, потому прошу тех, кто придумает куда можно применить вышеуказанные встроенные функции применить их, и рассказать о результатахsmile.gif
klen
я всегда думал что инлайн асм вставки для того и придуманы чтоб компиллер их ни прикаких обстоятельствах не трогал - а малоли чего там программер надумал? если былобы не так то (или небыло механизма асм вставок) то некоторые трюки нельзя былобы решить С-кодом вовсе - например crt код для armv4

я считаю что асм вставки тупо вставляются в код компиллером и все слитое предается транслятору асма.
Почему? во первых ВСЯ оптимизация происходит на промежуточном языке RTL, и только потом преобразуется в асм. соответстывенно когда асм вставка попадает в общий код после оптимизации. сам транслятор асма не оптимизирует - не его это дело, да и как? линкер может! например претусить расположение кусков кода(например функций) чтоб увеличить количество быстрых коротких вызовов и переходов если таковые есть в наборе команд проца и тп.

даже более того - встроенные функции - это "теже вставки" котрые уже обернуты в функции С. темболее что Вы утверждаете что исполняемый код не изменился.

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

Смотреть нада. Прелесть GCC в том что этот вопрос можно просто пронаблюдать по маршруру исходник->RTL->асм->объектник->объектник + либы->выходной elf бинарь -> файл прошивки

глядя на эти промежуточные результаты можно просто увидить различия двух вариантов и понять "кто виноват и чЁ делать"

если я не прав то поправте. ... вот теперь мучить мысль будет "а как ваще asm код можно соптимизировать..."
ARV
так ведь вроде бы даже в документации сказано, что ассемблерные вставки с псевдопараметрами в командах (те, которые %1, %2 и т.д.) компилятор "обрамляет" необходимыми командами для занесения в реальные регистры нужных значений и т.п., т.е. ассемблерная вставка вставляется не совсем 1 в 1, а с некими преобразованиями до и после нее как минимум. и второе наблюдение по поводу оптимизатора: asm("nop"); скорее всего исчезнет из кода на этапе оптимизации, а asm volatile ("nop"); останется однозначно - это ли не свидетельствует о том, что ассемблерные вставки подвергаются обработке оптимизатором?
AHTOXA
Цитата(klen @ Oct 26 2009, 14:09) *
я всегда думал что инлайн асм вставки для того и придуманы чтоб компиллер их ни прикаких обстоятельствах не трогал

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


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

------

Посмотрел повнимательнее. Я был не правsmile.gif Вся экономия произошла от того, что при употреблении __builtin_clz() компилер постеснялся заинлайнить одну функцию, содержащую вызов моей инлайн-функции. А при использовании встроенного ассемблера - заинлайнил.
То есть, похоже, вся разница в том, что __builtin_clz() добавляет к уровню вложенности вызовов ещё один уровень.
klen
Вы правы про обрамление. я забыл про него.
про размешение аргуметов (из которго обрамление выростае) это понятно - типа компиллер сделай так что операнд был в памяти (m) или в регистре ® или еще как, это указания в списке аргументов. Это понятно.
я почемуто имел ввиду чистую асм вставку... я обычно это тоже ручками прописываю, хотя конечно разумно в большинстве случаев раскидывание по регистрам и загрузку выгрузку ему доверить.

в принципе выкинуть asm("nop") ничего мешать не должно.


вывод один - все работает так как нада, и мы это ПОНИМАЕМ smile.gif
GetSmart
Цитата(klen @ Oct 27 2009, 15:53) *
в принципе выкинуть asm("nop") ничего мешать не должно.

Нда... Оптимизаторы...
Если программист поставил asm("nop") значит она реально нужна, не для того чтобы "вундеркинд-компилятор" (или вундеркинд-разработчик компилятора?) её выкинул. Довольно странно в GCC выглядит сочетание volatile asm("nop"), причём IAR такое сочетание не переваривает.
AHTOXA
Цитата(GetSmart @ Oct 27 2009, 15:35) *
Довольно странно в GCC выглядит сочетание volatile asm("nop"), причём IAR такое сочетание не переваривает.


Это потому что IAR не умеет оптимизировать ассемблерные вставкиsmile.gif

Потому:
Цитата(klen @ Oct 27 2009, 14:53) *
вывод один - все работает так как нада, и мы это ПОНИМАЕМ smile.gif


tongue.gif
klen
Цитата(GetSmart @ Oct 27 2009, 14:35) *
Нда... Оптимизаторы...
Если программист поставил asm("nop") значит она реально нужна, не для того чтобы "вундеркинд-компилятор" (или вундеркинд-разработчик компилятора?) её выкинул. Довольно странно в GCC выглядит сочетание volatile asm("nop"), причём IAR такое сочетание не переваривает.


стоп стоп стоп!!! видимо не все ПООНИМАЕМ ЧТО РАБОТЕТ ВСЕ ПРАВИЛЬНО!

если написать asm("nop") - то это явно ненужная штука - она ничего не делает.
а вот volatile asm("nop") - это очень даже много делает!!! компиллеру ясно показано что трогать НИЗЗЯЯЯ, программер не тупой и не с дуру это вписал.

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

теперь наверно "ОПЯТЬ ВСЕ ПОНИМАЕМ ПРАВИЛЬНО" biggrin.gif

сколько живу стока убеждаюсь - учебник по С для embedded нада начинать с главы про VOLATILE, а уж потом про оператры, переменные, функции и всякие там языковый конструкции. Это просто поразительно! lol.gif чем проще вещи тем сложнее понять ...

это все РС виноваты - "у них" нет прерываний, как многие считаю. за том есть Windows и те кого на ней "учили программить". Вопрос на засыпку. я вот фортранчиком не брезгую оформить куски счетные на stm32f103 а кто его вообще умеет ? rolleyes.gif

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

остапа понесло....
слово volatile для меня как валерьянка для кота... топорщит
GetSmart
Цитата(klen @ Oct 27 2009, 17:41) *
если написать asm("nop") - то это явно ненужная штука - она ничего не делает.
а вот volatile asm("nop") - это очень даже много делает!!! компиллеру ясно показано что трогать НИЗЗЯЯЯ, программер не тупой и не с дуру это вписал.

А по-моему, что с volatile, что без неё должно быть одно и то же. Асм использует программист и ему лучше знать, какие инструкции использовать, ну кроме загрузки констант в регистры, которые слишком запутанные и зависят от загружаемого значения. Для загрузок какой-нить макрос хорошо подошёл. А остальной код даже представить не могу, для чего его нужно оптимизировать. Поэтому в IARе не задействовано для asm приставка volatile.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.