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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> IAR AVR - когда вредна оптимизация...
Alechin
сообщение Oct 15 2007, 13:55
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 158
Регистрация: 27-06-05
Из: Химки, Моск.обл.
Пользователь №: 6 334



Убил несколько часов на выключение WDT в Mega88 в программе на Си.
Вот такой код
__watchdog_reset();
MCUSR &= ~(1 << WDRF);
WDTCSR |= (1 << WDCE) | (1 << WDE);
WDTCSR = 0x00;
IAR при оптимизации умудрился разбить на процедуры (cross call), в результате чего между последовательными записями в WDTCSR проходило более 4 тактов, и выключенный изначально WDT включался, не давая нормально загрузиться системе.
Побороть смог только вынеся данный код в процедуру с выключением оптимизации для нее (#pragme optimize=none).
Возник вопрос - ни какими ключевыми словами нельзя изменить уровень оптимизации для фрагмента кода С ВОЗВРАТОМ к текущему уровню оптимизации (через #pragma optimize можно только установить требуемый уровень оптимизации, но не вернуться к установленному в свойствах проекта, по крайней мере я не нашел другого)?
Go to the top of the page
 
+Quote Post
scifi
сообщение Oct 15 2007, 17:54
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Мне кажется, тут двух мнений быть не может: если нужно гарантировать не более 4-х тактов между инструкциями, то нужно писать на ассемблере. Иначе при каждом апгрейде версии компилятора и смене его настроек придётся проверять, как изменился этот кусок кода.
Go to the top of the page
 
+Quote Post
PSP
сообщение Oct 15 2007, 19:56
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 118
Регистрация: 1-10-07
Пользователь №: 30 988



И еще не забыть запретить прерывания. Иначе баг изменится с постоянного на случайно возникающий, что гораздо неприятнее.
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Oct 16 2007, 09:23
Сообщение #4


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(Alechin @ Oct 15 2007, 16:55) *
Побороть смог только вынеся данный код в процедуру с выключением оптимизации для нее (#pragme optimize=none).
Возник вопрос - ни какими ключевыми словами нельзя изменить уровень оптимизации для фрагмента кода С ВОЗВРАТОМ к текущему уровню оптимизации (через #pragma optimize можно только установить требуемый уровень оптимизации, но не вернуться к установленному в свойствах проекта, по крайней мере я не нашел другого)?

В руководстве сказано:
Цитата
The #pragma optimize directive is used for decreasing the optimization level, or for
turning off some specific optimizations. This pragma directive only affects the function
that follows immediately after the directive.

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

Цитата(scifi @ Oct 15 2007, 20:54) *
Мне кажется, тут двух мнений быть не может: если нужно гарантировать не более 4-х тактов между инструкциями, то нужно писать на ассемблере. Иначе при каждом апгрейде версии компилятора и смене его настроек придётся проверять, как изменился этот кусок кода.

Не стОит быть столь категоричным.
Если программа написана грамотно, то апдейт версии компилятора (по крайней мере в данном случае) к ухудшению ситуации не приведёт.
Go to the top of the page
 
+Quote Post
Alechin
сообщение Oct 16 2007, 15:22
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 158
Регистрация: 27-06-05
Из: Химки, Моск.обл.
Пользователь №: 6 334



Цитата
В руководстве сказано:
это означает, что данная директива действует только на одну, непосредственно следующую за ней, функцию.
На все последующие функции распространяется уровень оптимизации по умолчанию (заданный в настройках).

Это я знаю, поэтому так и сделал (вынес в функцию, и предварил данной прагмой). Вопрос в другом - не хотелось 3 строчки выносить в функцию. Поэтому хотелось бы написать прагму перед этими строчками, и прагму, возвращающую "взад" уровень оптимизации после этих строк (по-моему, но точно не помню, в Кейле, или в BCPP так можно было сделать).
Ну что-ж: нет так нет.

И еще просто удивила замена ОДНОЙ команды вызовом процедуры с этой-же командой! "Перебдел" компилятор при оптимизации.
Go to the top of the page
 
+Quote Post
xemul
сообщение Oct 16 2007, 16:36
Сообщение #6



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Код
#pragma optimize=none
inline static void foo(void)
{
   __watchdog_reset();
   MCUSR &= ~(1 << WDRF);
   cli();
   WDTCSR |= (1 << WDCE) | (1 << WDE);
   WDTCSR = 0x00;
   sei();
}
Go to the top of the page
 
+Quote Post
Runner
сообщение Apr 23 2009, 15:41
Сообщение #7


Частый гость
**

Группа: Свой
Сообщений: 107
Регистрация: 18-06-05
Пользователь №: 6 117



Цитата(xemul @ Oct 16 2007, 18:36) *
Код
#pragma optimize=none
inline static void foo(void)
{
   __watchdog_reset();
   MCUSR &= ~(1 << WDRF);
   cli();
   WDTCSR |= (1 << WDCE) | (1 << WDE);
   WDTCSR = 0x00;
   sei();
}


Вопрос знатокам: в указаном примере функция foo будет встраиваться? Мне inlining удается только когда поставлена опция оптимизации - high, а иначе RCALL foo. Не помогает даже #pragma inline=forced. (IARAVR 5.11B) unsure.gif
Go to the top of the page
 
+Quote Post
IgorMarx
сообщение Apr 23 2009, 20:05
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 5-10-05
Из: Зеленоград
Пользователь №: 9 268



Цитата(Runner @ Apr 23 2009, 19:41) *
Вопрос знатокам: в указаном примере функция foo будет встраиваться? Мне inlining удается только когда поставлена опция оптимизации - high, а иначе RCALL foo. Не помогает даже #pragma inline=forced. (IARAVR 5.11B) unsure.gif


Самая вероятная ситуация: будет в релизе со включенной оптимизацией (а может и нет), в дебажной - будет отдельной процедурой.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Apr 23 2009, 21:37
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(Runner @ Apr 23 2009, 18:41) *
Вопрос знатокам: в указаном примере функция foo будет встраиваться? Мне inlining удается только когда поставлена опция оптимизации - high, а иначе RCALL foo. Не помогает даже #pragma inline=forced. (IARAVR 5.11B) unsure.gif


В умных книгах написано, что компилятор не обязан встраивать inline функции, если с его точки зрения это хуже, чем вызвать обычную функцию.
См. Герб Саттер. Новые сложные задачи на С++.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 24 2009, 06:53
Сообщение #10


Гуру
******

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



Цитата(IgorMarx @ Apr 23 2009, 23:05) *
будет в релизе со включенной оптимизацией (а может и нет), в дебажной - будет отдельной процедурой.
А что, у компилятора или линкера есть какая то магическая опция "релизная версия"?


--------------------
На любой вопрос даю любой ответ
"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
MrYuran
сообщение Apr 24 2009, 07:06
Сообщение #11


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

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



Цитата(Сергей Борщ @ Apr 24 2009, 10:53) *
А что, у компилятора или линкера есть какая то магическая опция "релизная версия"?

Есть переключение target-а на release/debug
Это опция не компилятора/линкера, а такой жёлтенькой оболочки IAR EWB
Причём и в том, и в другом можно задать любой уровень оптимизации, но по умолчанию в дебаге включен по-моему, "Best debug support", который отключает оптимизацию вообще


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


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Runner @ Apr 23 2009, 18:41) *
Вопрос знатокам: в указаном примере функция foo будет встраиваться?

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


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 24 2009, 10:00
Сообщение #13


Гуру
******

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



Цитата(MrYuran @ Apr 24 2009, 10:06) *
Это опция не компилятора/линкера, а такой жёлтенькой оболочки IAR EWB
В том то и дело. Это название совокупности галочек в настройках, расставленных оболочкой по умолчанию. Т.е. нельзя говорить о том, что поведение будет зависеть от выбора в оболочке target release или target debug. Поведение будет полностью определяться положением галочек, расставленных в оболочке, но никак не названием этого target.


Цитата(Dog Pawlowa @ Apr 24 2009, 11:38) *
Поскольку может быть встроена функция только в том же файле, где определена, встает вопрос вообще о правильности пути для более-менее серьезного проекта.
Путь однозначно правильный. Если нужно, функции с квалификатором inline, также как и static, могут быть вынесены в заголовочный файл. Объявление в виде функции (в отличие от макроса) возлагает на компилятор заботу о контроле правильности типов, а также о создании временных переменных для хранения параметров. Просто надо разобраться, почему не работает #pragma inline=forced. Возможно, они перешли на _Pragma("inline = forced"). И зачем вообще компилировать с оптимизацией, отличной от high - тоже совсем другой разговор.


--------------------
На любой вопрос даю любой ответ
"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
Dog Pawlowa
сообщение Apr 24 2009, 10:50
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Сергей Борщ @ Apr 24 2009, 13:00) *
Объявление в виде функции (в отличие от макроса) возлагает на компилятор заботу о контроле правильности типов, а также о создании временных переменных для хранения параметров.

В общем случае все это так, но если глянуть, с чего все начиналось у топикстартера, и какие же там переменные используются, то лично у меня вопрос остается.
Это просто разный инструмент, как вилка и ложка. Ложкой безопаснее, но вилкой в умелых то руках можно за два удара восемь дырок.... biggrin.gif


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
tourist
сообщение Apr 24 2009, 12:08
Сообщение #15


Участник
*

Группа: Участник
Сообщений: 29
Регистрация: 6-04-09
Из: Донецк
Пользователь №: 47 247



Цитата(Dog Pawlowa @ Apr 24 2009, 14:50) *
В общем случае все это так, но если глянуть, с чего все начиналось у топикстартера, и какие же там переменные используются, то лично у меня вопрос остается.

При записи вида:
Код
WDTCSR |= (1 << WDCE) | (1 << WDE);

Компилятор действительно генерит код не укладывающийся в 4 такта...
Я решал проблему, описываемую автором темы, записью нужного числа непосредственно в регистр, типа того:
Код
WDTCSR |= 0x01;

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

Сообщение отредактировал tourist - Apr 24 2009, 12:13


--------------------
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 6th July 2025 - 11:12
Рейтинг@Mail.ru


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