Alechin 0 15 октября, 2007 Опубликовано 15 октября, 2007 · Жалоба Убил несколько часов на выключение 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 можно только установить требуемый уровень оптимизации, но не вернуться к установленному в свойствах проекта, по крайней мере я не нашел другого)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 15 октября, 2007 Опубликовано 15 октября, 2007 · Жалоба Мне кажется, тут двух мнений быть не может: если нужно гарантировать не более 4-х тактов между инструкциями, то нужно писать на ассемблере. Иначе при каждом апгрейде версии компилятора и смене его настроек придётся проверять, как изменился этот кусок кода. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
PSP 0 15 октября, 2007 Опубликовано 15 октября, 2007 · Жалоба И еще не забыть запретить прерывания. Иначе баг изменится с постоянного на случайно возникающий, что гораздо неприятнее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 16 октября, 2007 Опубликовано 16 октября, 2007 · Жалоба Побороть смог только вынеся данный код в процедуру с выключением оптимизации для нее (#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. это означает, что данная директива действует только на одну, непосредственно следующую за ней, функцию. На все последующие функции распространяется уровень оптимизации по умолчанию (заданный в настройках). Мне кажется, тут двух мнений быть не может: если нужно гарантировать не более 4-х тактов между инструкциями, то нужно писать на ассемблере. Иначе при каждом апгрейде версии компилятора и смене его настроек придётся проверять, как изменился этот кусок кода. Не стОит быть столь категоричным. Если программа написана грамотно, то апдейт версии компилятора (по крайней мере в данном случае) к ухудшению ситуации не приведёт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alechin 0 16 октября, 2007 Опубликовано 16 октября, 2007 · Жалоба В руководстве сказано: это означает, что данная директива действует только на одну, непосредственно следующую за ней, функцию. На все последующие функции распространяется уровень оптимизации по умолчанию (заданный в настройках). Это я знаю, поэтому так и сделал (вынес в функцию, и предварил данной прагмой). Вопрос в другом - не хотелось 3 строчки выносить в функцию. Поэтому хотелось бы написать прагму перед этими строчками, и прагму, возвращающую "взад" уровень оптимизации после этих строк (по-моему, но точно не помню, в Кейле, или в BCPP так можно было сделать). Ну что-ж: нет так нет. И еще просто удивила замена ОДНОЙ команды вызовом процедуры с этой-же командой! "Перебдел" компилятор при оптимизации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xemul 0 16 октября, 2007 Опубликовано 16 октября, 2007 · Жалоба #pragma optimize=none inline static void foo(void) { __watchdog_reset(); MCUSR &= ~(1 << WDRF); cli(); WDTCSR |= (1 << WDCE) | (1 << WDE); WDTCSR = 0x00; sei(); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Runner 0 23 апреля, 2009 Опубликовано 23 апреля, 2009 · Жалоба #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: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorMarx 0 23 апреля, 2009 Опубликовано 23 апреля, 2009 · Жалоба Вопрос знатокам: в указаном примере функция foo будет встраиваться? Мне inlining удается только когда поставлена опция оптимизации - high, а иначе RCALL foo. Не помогает даже #pragma inline=forced. (IARAVR 5.11B) :unsure: Самая вероятная ситуация: будет в релизе со включенной оптимизацией (а может и нет), в дебажной - будет отдельной процедурой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 23 апреля, 2009 Опубликовано 23 апреля, 2009 · Жалоба Вопрос знатокам: в указаном примере функция foo будет встраиваться? Мне inlining удается только когда поставлена опция оптимизации - high, а иначе RCALL foo. Не помогает даже #pragma inline=forced. (IARAVR 5.11B) :unsure: В умных книгах написано, что компилятор не обязан встраивать inline функции, если с его точки зрения это хуже, чем вызвать обычную функцию. См. Герб Саттер. Новые сложные задачи на С++. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 121 24 апреля, 2009 Опубликовано 24 апреля, 2009 · Жалоба будет в релизе со включенной оптимизацией (а может и нет), в дебажной - будет отдельной процедурой.А что, у компилятора или линкера есть какая то магическая опция "релизная версия"? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 17 24 апреля, 2009 Опубликовано 24 апреля, 2009 · Жалоба А что, у компилятора или линкера есть какая то магическая опция "релизная версия"? Есть переключение target-а на release/debug Это опция не компилятора/линкера, а такой жёлтенькой оболочки IAR EWB Причём и в том, и в другом можно задать любой уровень оптимизации, но по умолчанию в дебаге включен по-моему, "Best debug support", который отключает оптимизацию вообще Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 24 апреля, 2009 Опубликовано 24 апреля, 2009 · Жалоба Вопрос знатокам: в указаном примере функция foo будет встраиваться? Поскольку может быть встроена функция только в том же файле, где определена, встает вопрос вообще о правильности пути для более-менее серьезного проекта. Может быть, макрос? Оптимизатор не увидит смысла экономить на эпилогах - их просто не будет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 121 24 апреля, 2009 Опубликовано 24 апреля, 2009 · Жалоба Это опция не компилятора/линкера, а такой жёлтенькой оболочки IAR EWBВ том то и дело. Это название совокупности галочек в настройках, расставленных оболочкой по умолчанию. Т.е. нельзя говорить о том, что поведение будет зависеть от выбора в оболочке target release или target debug. Поведение будет полностью определяться положением галочек, расставленных в оболочке, но никак не названием этого target. Поскольку может быть встроена функция только в том же файле, где определена, встает вопрос вообще о правильности пути для более-менее серьезного проекта.Путь однозначно правильный. Если нужно, функции с квалификатором inline, также как и static, могут быть вынесены в заголовочный файл. Объявление в виде функции (в отличие от макроса) возлагает на компилятор заботу о контроле правильности типов, а также о создании временных переменных для хранения параметров. Просто надо разобраться, почему не работает #pragma inline=forced. Возможно, они перешли на _Pragma("inline = forced"). И зачем вообще компилировать с оптимизацией, отличной от high - тоже совсем другой разговор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 24 апреля, 2009 Опубликовано 24 апреля, 2009 · Жалоба Объявление в виде функции (в отличие от макроса) возлагает на компилятор заботу о контроле правильности типов, а также о создании временных переменных для хранения параметров. В общем случае все это так, но если глянуть, с чего все начиналось у топикстартера, и какие же там переменные используются, то лично у меня вопрос остается. Это просто разный инструмент, как вилка и ложка. Ложкой безопаснее, но вилкой в умелых то руках можно за два удара восемь дырок.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tourist 0 24 апреля, 2009 Опубликовано 24 апреля, 2009 (изменено) · Жалоба В общем случае все это так, но если глянуть, с чего все начиналось у топикстартера, и какие же там переменные используются, то лично у меня вопрос остается. При записи вида: WDTCSR |= (1 << WDCE) | (1 << WDE); Компилятор действительно генерит код не укладывающийся в 4 такта... Я решал проблему, описываемую автором темы, записью нужного числа непосредственно в регистр, типа того: WDTCSR |= 0x01; При этом (как ни странно) код получается нормальный, даже с полной оптимизацией, и число попадает в регистр без лишних тедлодвижений... ИМХО автор перемудрил с отключением оптимизации для функции... Изменено 24 апреля, 2009 пользователем tourist Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться