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

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> IAR AVR - когда вредна оптимизация...
Dog Pawlowa
сообщение Apr 29 2009, 16:46
Сообщение #16


Гуру
******

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



Вот, наткнулся на свои макросы...
Хм, запрета прерывания нет, но работает... Ах, да... Я же WDT никогда не отключаю.
Вот таким косвенным путем происходит обучение правильному использованию ресурсов контроллера smile.gif

Код
#define WDT_OFF        {    __watchdog_reset(void); WDTCR |= (1<<WDTOE) | (1<<WDE);    WDTCR=0; }
#define WDT_ON        {    WDTCR=(1<<WDE);}
#define WDT_RESET    {    __watchdog_reset(); }


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Dir
сообщение May 5 2009, 12:01
Сообщение #17


Местный
***

Группа: Свой
Сообщений: 201
Регистрация: 6-01-05
Пользователь №: 1 830



Цитата(tourist @ Apr 24 2009, 15:08) *
При записи вида:
Код
WDTCSR |= (1 << WDCE) | (1 << WDE);

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

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


Вот именно, что все это очень странно. Насколько меня учили, порты в МК - это volatile-переменные, поэтому компилятор при оптимизации должен позаботиться о всех сторонних эффектах, если он претендует на совместимость со стандартом "С". Т.е. явное игнорирование разработчиками компилятора стандарта. Попросту говоря, баг. Или не так?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 5 2009, 12:03
Сообщение #18


Гуру
******

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



Цитата(Dir @ May 5 2009, 15:01) *
Т.е. явное игнорирование разработчиками компилятора стандарта. Попросту говоря, баг. Или не так?
В чем тут игнорирование стандарта?


--------------------
На любой вопрос даю любой ответ
"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
сообщение May 5 2009, 12:13
Сообщение #19


Гуру
******

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



Я бы сформулировал по другому:
Имеет ли право Атмел приводить пример сишного текста программы работы с WDT, если конкретная реализация в машинных кодах зависит от компилятора.

Короче, так - если у автора текст не совпадает полностью с примером в даташит - не прав автор.
Если текст совпадает - не прав Атмел.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Dir
сообщение May 5 2009, 12:21
Сообщение #20


Местный
***

Группа: Свой
Сообщений: 201
Регистрация: 6-01-05
Пользователь №: 1 830



Цитата(Сергей Борщ @ May 5 2009, 15:03) *
В чем тут игнорирование стандарта?

Есть там глава про сторонние эффекты и volatile-переменные. Нужно, конечно, рыться и внимательно читать, но, по памяти, стандарт прямо запрещает оптимизацию ДАЖЕ по времени, если в этом принимают участие volatile-переменные. А тут работу препроцессора взял на себя компилятор и оптимизировал как хотел... Компилятор НЕ ИМЕЛ ПРАВА на такие вольности.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 5 2009, 13:07
Сообщение #21


Гуру
******

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



Цитата(Dir @ May 5 2009, 15:21) *
но, по памяти, стандарт прямо запрещает оптимизацию ДАЖЕ по времени, если в этом принимают участие volatile-переменные.
Освежите. В стандарте нет ни слова о времени. Компилятор обязан выполнить все указанные в программе обращения (на чтения и запись) к volatile-переменным и не имеет права нарушить их последовательность. Все. НА этом обязанности компилятора заканчиваются.
Цитата(Dir @ May 5 2009, 15:21) *
А тут работу препроцессора взял на себя компилятор и оптимизировал как хотел... Компилятор НЕ ИМЕЛ ПРАВА на такие вольности.
Где оптимизация? Где работа препроцессора? Где вольности в конце концов? Компилятор сделал чтение-наложение маски-запись. Все как заказывали. С точки зрения стандарта никаких нарушений.


--------------------
На любой вопрос даю любой ответ
"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
Dir
сообщение May 5 2009, 14:12
Сообщение #22


Местный
***

Группа: Свой
Сообщений: 201
Регистрация: 6-01-05
Пользователь №: 1 830



Цитата(Сергей Борщ @ May 5 2009, 16:07) *
Освежите. В стандарте нет ни слова о времени. Компилятор обязан выполнить все указанные в программе обращения (на чтения и запись) к volatile-переменным и не имеет права нарушить их последовательность. Все. НА этом обязанности компилятора заканчиваются.Где оптимизация? Где работа препроцессора? Где вольности в конце концов? Компилятор сделал чтение-наложение маски-запись. Все как заказывали. С точки зрения стандарта никаких нарушений.

Тогда вообще ничего не понятно.
Почему, как указывалось в http://electronix.ru/forum/index.php?showt...st&p=583723

"Код
WDTCSR |= (1 << WDCE) | (1 << WDE);
Компилятор действительно генерит код не укладывающийся в 4 такта...
Я решал проблему, описываемую автором темы, записью нужного числа непосредственно в регистр, типа того:
Код
WDTCSR |= 0x01;
При этом (как ни странно) код получается нормальный, даже с полной оптимизацией, и число попадает в регистр без лишних тедлодвижений..."

Ведь после препроцессора компилятору попадает один и тот же код! Понятно, что препроцессор в стандарт не входит, но ведь получается, что "с точки зрения стандарта" компилятор вполне может разбить константное выражение и использовать его часть для своих оптимизационных ухищрений.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 5 2009, 16:12
Сообщение #23


Гуру
******

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



Цитата(Dir @ May 5 2009, 17:12) *
Ведь после препроцессора компилятору попадает один и тот же код!
Нет, разный. В одном случае установлен 1 бит, и компилятор генерит инструкцию sbi, во втором случае 2 бита, и иначе как через in, or, out не получится. А еще проще не использовать в этой конструкции "или" вообще - сразу писать нужное число. Потому что состояние остальных битов, как правило, известно заранее:
Код
    WDTCR = (1<<WDCE)|(1<<WDE);
    WDTCR = (1<<WDP2)|(1<<WDP1);


--------------------
На любой вопрос даю любой ответ
"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
Dir
сообщение May 5 2009, 17:57
Сообщение #24


Местный
***

Группа: Свой
Сообщений: 201
Регистрация: 6-01-05
Пользователь №: 1 830



Цитата(Сергей Борщ @ May 5 2009, 19:12) *
Нет, разный. В одном случае установлен 1 бит, и компилятор генерит инструкцию sbi, во втором случае 2 бита, и иначе как через in, or, out не получится. А еще проще не использовать в этой конструкции "или" вообще - сразу писать нужное число. Потому что состояние остальных битов, как правило, известно заранее:
Код
    WDTCR = (1<<WDCE)|(1<<WDE);
    WDTCR = (1<<WDP2)|(1<<WDP1);


Ну, я воспринял это просто как пример. Типа автору стало лень считать HEX-содержание своего кода.... и понесся обосновывать smile.gif
А вот сейчас в спокойной обстановке дома решил исследовать что же на самом деле происходит и ... чешу затылок. Мне никак не удается при любых уровнях оптимизации и вообще без нее добиться того, чтобы компилятор по разному оттранслировал процедуру инициализации WDT.
Т.е. вот такой код независимо от того стоит перед ним #pragma optimize=none или нет, написаны команды инициализации в виде команд препроцессору или в виде чисел (закоментарено) все равно транслируются одинаково.
Код
void test_WDT(void)
{
    __watchdog_reset();
    WDTCSR=(1<<WDCE)|(1<<WDE)|(1<<WDP0);
    WDTCSR=(1<<WDE)|(1<<WDP0);
//    WDTCSR=0x19;
//    WDTCSR=0x09;
}


ассемблерный код
Код
      7              __watchdog_reset();
   \   00000000   95A8               WDR
      8              WDTCSR=(1<<WDCE)|(1<<WDE)|(1<<WDP0);
   \   00000002   E109               LDI     R16, 25
   \   00000004   93000060           STS     96, R16
      9              WDTCSR=(1<<WDE)|(1<<WDP0);
   \   00000008   E009               LDI     R16, 9
   \   0000000A   93000060           STS     96, R16

Наверное поэтому никогда раньше не задумывался над этим вопросом, хотя по привычке всегда использовал #pragma optimize=none
Может быть с оптимизацией таки можно заставить компилятор генерировать вызовы функций посредине двух WDTCSR = ..., но надо таки постараться не по детски smile.gif
PS. Компилятор последний, 5.20, для примера взята mega48
Go to the top of the page
 
+Quote Post

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

 


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


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