Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как деликатнее настроить оптимизацию AVG-GCC
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
RodionGork
Уважаемые товарищи!

Вероятно тема уже хорошо зажеванная - но по ключевым словам "оптимизация" и "gcc" вываливается кошмарная масса ссылок - найти нужную я не в силах. ;-)

Речь идет о следующем. Контроллер (mega32) работает на 2МГц и больше сделать нельзя по "другим причинам". Каждый цикл длится 2000мкс, за это время происходит несколько несложных вещей:
- проводятся измерения;
- осуществляется передача данных;
- осуществляется прием синхрокоманды.

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

Пока все происходит при помощи Win-AVR

И тут я обнаруживаю, что с директивой компилятора -O0 компилятор даже три простые действия очень плохо умещает в отведенное время. Еще бы: например "PORTD|=(1<<6)" превращается в конструкцию из шести команд, суть которых в том чтобы взять значение из адреса памяти, соответствующего регистру и после манипуляций с ним туда же его вернуть.

Ладно, ставлю -O1 или -O2 - тогда компилятор разом вспоминает про инструкции sbi для этих случаев - ну умница! Однако при этом же он, как я наблюдаю, клонирует код и даже местами переставляет его. Из-за этого я очень плохо понимаю что вообще происходит и, что гораздо хуже, не могу точно определить где и сколько микросекунд проходит.

Можно ли ему как-то деликатно объяснить, чтобы избавил меня от этой "прыжковой оптимизации", но сохранил всю остальную?

Родион
XVR
Запускаете gcc -v --help и в полученной портянке внимательно изучаете все опции оптимизации (нечто, начинающееся с -f...)
RodionGork
Цитата(XVR @ Sep 22 2009, 11:08) *
Запускаете gcc -v --help и в полученной портянке внимательно изучаете все опции оптимизации (нечто, начинающееся с -f...)


Ну да... Я нашел этот же перечень в одной из портянок в папке docs... Видимо, зря потревожил эфир... Правда "не нравится мне все это" - получается, что программулина на Си будет состоять на 50% из ассемблерных вставок и все равно правильно будет работать, только если я каждый раз при компиляции буду правильно опции оптимизации писать. Переносимостью что-то не пахнет %-)
MrYuran
Цитата(RodionGork @ Sep 22 2009, 11:30) *
Переносимостью что-то не пахнет %-)

Ну уж что-нибудь одно, либо переносимость, либо с точностью до такта rolleyes.gif
Опять же, переносимость - понятие относительное.
Для переносимости проект лучше поделить на 2 части: common и platform specific.
Причём, специфика может быть как у аппаратной, так и у программной платформы.

Я обычно ставлю оптимизацию -O3 (максимальная по быстродействию), а по размеру -
CFLAGS += -ffunction-sections -fdata-sections
помещает каждый объект в отдельную секцию, а линкер потом выкидывает неиспользуемые.

Искать лучше не где попало, а по форуму. Здесь много таких тем.
Сергей Борщ
Цитата(RodionGork @ Sep 22 2009, 09:41) *
И тут я обнаруживаю, что с директивой компилятора -O0 компилятор даже три простые действия очень плохо умещает в отведенное время. Еще бы: например "PORTD|=(1<<6)" превращается в конструкцию из шести команд, суть которых в том чтобы взять значение из адреса памяти, соответствующего регистру и после манипуляций с ним туда же его вернуть.
А теперь подумайте логически. -O0 заставляет компилятор отключить оптимизацию напрочь. Что вы написали в команде? "Взять содержимое PORTD, сделать ИЛИ c 0x40, записать результат в PORTD". Что сделал компилятор? В точности то, что вы просили. Какие претензии? -O0 использовать не нужно никогда! Для AVR используйте только -Os.
Поищите по форуму расширенным поиском по слову "оптимизация" и имени пользователя aesok, он частенько описывал разные ключи.
Цитата(RodionGork @ Sep 22 2009, 09:41) *
Ладно, ставлю -O1 или -O2 - тогда компилятор разом вспоминает про инструкции sbi для этих случаев - ну умница! Однако при этом же он, как я наблюдаю, клонирует код и даже местами переставляет его. Из-за этого я очень плохо понимаю что вообще происходит
Он делает код для контроллера. Ну не может он генерить код, подстраиваясь под меру понимания конкретного программиста.
Цитата(RodionGork @ Sep 22 2009, 09:41) *
и, что гораздо хуже, не могу точно определить где и сколько микросекунд проходит.
Прогоните код в симуляторе, или, еще лучше, дергайте ногой в ключевых точках и смотрите осциллографом.
Цитата(RodionGork @ Sep 22 2009, 09:41) *
Можно ли ему как-то деликатно объяснить, чтобы избавил меня от этой "прыжковой оптимизации", но сохранил всю остальную?
Давайте на конкретных примерах, что значит "прыжковая оптимизация".
Legotron
А мне кажется, что программа должна быть написана таким образом, чтобы оптимизация сильно не влияла на ее работу. Временные интервалы, периоды таймера, частота кварца должны выбираться с запасом, чтобы +-100 тактов роли не играли. Чтобы не тратить время на чтения дизасемблера.
Мое резюме такое: ассемблерных вставок должно быть не более 10-20% кода, если получается иначе, то можно подумать о том, чтобы писать на чистом ассемблере, если уж у вас устройство критично по потреблению, что вы не можете взвинтить тактовую.
Всё гениальное просто smile.gif
Сергей Борщ
Цитата(RodionGork @ Sep 22 2009, 10:30) *
Правда "не нравится мне все это" - получается, что программулина на Си будет состоять на 50% из ассемблерных вставок
Если хотите с точностью до такта - генерите ассемблерный исходник, правьте его руками. Будет 100% повторяемо.
Цитата(RodionGork @ Sep 22 2009, 10:30) *
и все равно правильно будет работать, только если я каждый раз при компиляции буду правильно опции оптимизации писать.
С точки зрения языка С время выполнения не является критерием правильности. Все остальные критерии можно удовлетворить, если писать правильно. Для этого надо изучать язык.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.