реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Как деликатнее настроить оптимизацию AVG-GCC
RodionGork
сообщение Sep 22 2009, 06:41
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 239
Регистрация: 30-10-07
Из: Санкт-Петербург
Пользователь №: 31 866



Уважаемые товарищи!

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

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

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

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

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

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

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

Родион
Go to the top of the page
 
+Quote Post
XVR
сообщение Sep 22 2009, 07:08
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Запускаете gcc -v --help и в полученной портянке внимательно изучаете все опции оптимизации (нечто, начинающееся с -f...)
Go to the top of the page
 
+Quote Post
RodionGork
сообщение Sep 22 2009, 07:30
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 239
Регистрация: 30-10-07
Из: Санкт-Петербург
Пользователь №: 31 866



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


Ну да... Я нашел этот же перечень в одной из портянок в папке docs... Видимо, зря потревожил эфир... Правда "не нравится мне все это" - получается, что программулина на Си будет состоять на 50% из ассемблерных вставок и все равно правильно будет работать, только если я каждый раз при компиляции буду правильно опции оптимизации писать. Переносимостью что-то не пахнет %-)
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Sep 22 2009, 08:51
Сообщение #4


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(RodionGork @ Sep 22 2009, 11:30) *
Переносимостью что-то не пахнет %-)

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

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

Искать лучше не где попало, а по форуму. Здесь много таких тем.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 22 2009, 08:51
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(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) *
Можно ли ему как-то деликатно объяснить, чтобы избавил меня от этой "прыжковой оптимизации", но сохранил всю остальную?
Давайте на конкретных примерах, что значит "прыжковая оптимизация".


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Legotron
сообщение Sep 22 2009, 08:52
Сообщение #6


инопланетянин
***

Группа: Свой
Сообщений: 236
Регистрация: 24-12-06
Из: Питер
Пользователь №: 23 832



А мне кажется, что программа должна быть написана таким образом, чтобы оптимизация сильно не влияла на ее работу. Временные интервалы, периоды таймера, частота кварца должны выбираться с запасом, чтобы +-100 тактов роли не играли. Чтобы не тратить время на чтения дизасемблера.
Мое резюме такое: ассемблерных вставок должно быть не более 10-20% кода, если получается иначе, то можно подумать о том, чтобы писать на чистом ассемблере, если уж у вас устройство критично по потреблению, что вы не можете взвинтить тактовую.
Всё гениальное просто smile.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 22 2009, 08:55
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th June 2025 - 00:50
Рейтинг@Mail.ru


Страница сгенерированна за 0.01471 секунд с 7
ELECTRONIX ©2004-2016