|
|
  |
IAR MSP430 заоптимизировал?, Как его уговорить это не делать? |
|
|
|
Jun 8 2007, 07:48
|

Местный
  
Группа: Свой
Сообщений: 426
Регистрация: 20-01-05
Из: Зеленоград
Пользователь №: 2 070

|
Цитата(Dog Pawlowa @ Jun 8 2007, 11:02)  Оказывается, что компилятор выкидывает присвоение переменной. Не вижу никакого выкидывания. pump_state кешируется в R14. В зависимости от missing_pulses в R14 пишется либо 0 (001F94), либо 1 (001F98), после чего R14 сохраняется в pump_state (001F9A). Просто компилятор чуть-чуть не попал с комментариями - это простительно на высоких уровнях оптимизации. P.S. Основной источник глюков при использовании прерываний - программист, не знающий про ключевое слово volatile.
|
|
|
|
|
Jun 8 2007, 11:39
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(vmp @ Jun 8 2007, 10:48)  Не вижу никакого выкидывания. pump_state кешируется в R14. В зависимости от missing_pulses в R14 пишется либо 0 (001F94), либо 1 (001F98), после чего R14 сохраняется в pump_state (001F9A). Просто компилятор чуть-чуть не попал с комментариями - это простительно на высоких уровнях оптимизации. Спасибо. Действительно, погорячился. Простительно - отладчик в прерываниях ведет себя неадекватно, запаниковал. Цитата(vmp @ Jun 8 2007, 10:48)  P.S. Основной источник глюков при использовании прерываний - программист, не знающий про ключевое слово volatile. Никогда не называл себя программистом :-) А поясните, пожалуйста. volatile на самом то деле указано для pump_state. И я думаю, что это совершенно не нужно. Если переменная используется ТОЛЬКО в прерывании, то volatile на самом то деле и не нужно, правда?
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jun 8 2007, 11:50
|

Местный
  
Группа: Свой
Сообщений: 426
Регистрация: 20-01-05
Из: Зеленоград
Пользователь №: 2 070

|
Цитата(Dog Pawlowa @ Jun 8 2007, 15:39)  Если переменная используется ТОЛЬКО в прерывании, то volatile на самом то деле и не нужно, правда? Если только в одном невложенном прерывании - то не нужно. Если только в основной программе - тоже не нужно. Если и в основной программе и в прерывании - необходимо. Если в двух вложенных прерываниях - необходимо. Короче говоря, volatile надо ставить на те переменные, которые могут изменяться асинхронно. Или в прерываниях, или по DMA, или ещё как-нибудь (напрммер, регистры внешних устройств). Такие переменные компилятор не кеширует в регистрах процессора, а берет всегда свежие данные из ОЗУ.
|
|
|
|
|
Jun 8 2007, 14:20
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(vmp @ Jun 8 2007, 14:50)  Короче говоря, volatile надо ставить на те переменные, которые могут изменяться асинхронно. Спасибо, я так и представлял. Признаюсь, в старых проектах не пользовался. Тем не менее все вроде-бы работает, а теперь менять вроде бы ни к чему ("Папа, а почему солнце всходит на востоке, а заходит на западе? - Проверял? - Проверял! - Работает? - Работает! - Только ничего не меняй! "). Видимо, когда количество переменных достаточно велико, компилятор не может расположить эти переменные в регистрах ввиду их сравнительно редкого использования и берет из памяти.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jun 8 2007, 16:32
|

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

|
Цитата(Dog Pawlowa @ Jun 8 2007, 17:20)  Видимо, когда количество переменных достаточно велико, компилятор не может расположить эти переменные в регистрах ввиду их сравнительно редкого использования и берет из памяти. на конструкцию Код flag = 0; while(flag != 1); много регистров не нужно. Если flag не volatile, то при слабой оптимизаци компилятор считает flag в регистр и далее будет тупо проверять регистр, хороший - заменит эту конструкцию на бесконечный цикл, ибо внутри цикла flag не меняется и проверять его снова не нужно.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 8 2007, 20:26
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(Сергей Борщ @ Jun 8 2007, 19:32)  на конструкцию Код flag = 0; while(flag != 1); много регистров не нужно. Тем не менее постоянно использую такое: Код __no_init int delay_count; void Delay(int ms) { StartDelay(ms); while(delay_count>0) CheckTimeAndResetWDT(); } Повезло? Ребят, знал бы, что программировать так сложно - ни за что бы не брался!
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jun 9 2007, 06:36
|

Местный
  
Группа: Свой
Сообщений: 426
Регистрация: 20-01-05
Из: Зеленоград
Пользователь №: 2 070

|
Цитата(Dog Pawlowa @ Jun 9 2007, 00:26)  Тем не менее постоянно использую такое: Код __no_init int delay_count; void Delay(int ms) { StartDelay(ms); while(delay_count>0) CheckTimeAndResetWDT(); } Повезло? Если CheckTimeAndResetWDT() - это функция, а не макрос, то все в порядке. Компилятор в общем случае ничего о ней не знает и поэтому считает, что она может изменить все глобальные переменные, в том числе и delay_count.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|