Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вредная оптимизация
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
ruslannd
Пишу для STM32F1 на С под Keil

Есть кусок кода:

Код
    mtable_do_steps = 1;
    while (mtable_do_steps != 0);


переменная обращается в 0 в прерываниях. Все замечательно работает, если не включать оптимизациию.
Если включать, то вваливаемся в ступор(((

совсем не включать нельзя - недостаточно мощный проц и разлапистый код.

Как отключить оптимизацию только для этих двух строк?

Заранее спасибо
SSerge
Вам надо срочно найти учебник по С и прочитать там про ключевое слово volatile.
Mihey_K
Добавлю, что при включенной оптимизации если пишете в прерывании в глобальную переменную, всегда делайте ее volatile. Иначе компилятор просто не понимает, кто изменяет ее значение, и может, например, выпилить даже цикл, как бесполезный.
Сергей Борщ
Цитата(Mihey_K @ Jul 15 2015, 07:11) *
если пишете в прерывании в глобальную переменную, всегда делайте ее volatile.
Такой совет скорее из серии вредных. Во-первых, для глобальной переменной, которая пишется/читается только в невытесняющих друг друга прерываний volatile не нужен. Он даже лишний, ибо связывает руки оптимизатору и заставляет программиста в погоне за скоростью/размером раздувать исходник ненужными ручными кешированиями такой переменной во временные. Во-вторых переменная, которая читается в прерывании, а пишется в основном цикле или в вытесняющем прерывании volatile тоже обязателен. То есть полностью правило звучит так: volatile обязателен для переменных, которые используются в нескольких потоках управления (неважно каких - прерывание и основной цикл, два вытесняющих прерывания, два потока/процесса/нити в ОС и т.п.).
megajohn
Цитата(Сергей Борщ @ Jul 15 2015, 10:00) *
Во-первых, ... volatile не нужен.
Во-вторых ... volatile тоже обязателен.


наверное НЕ пропустили
ruslannd
Помогло. Спасибо.
Сергей Борщ
Цитата(megajohn @ Jul 15 2015, 10:06) *
наверное НЕ пропустили
Нет, все верно. В первом случае компилятор обязан считать значение из переменной после входа в обработчик и записать новое значение в переменную до выхода из обработчика. В промежутке между этими действиями значение переменной нигде кроме обработчика не используется, volatile не нужен и даже вреден.
Во втором случае volatile нужен, так как заставляет компилятор сразу же записать новое значение в переменную (запрещает откладывать запись) и это новое значение станет доступно прерыванию, другому потоку и т.д. "Тоже" имелось в виду "а не только в процитированном случае".
demiurg_spb
Цитата(ruslannd @ Jul 15 2015, 10:21) *
Помогло. Спасибо.

Аминь три раза)))
amaora
А я как-то обхожусь без volatile. В вашем случае можно например вызывать в цикле функцию пустышку из другого модуля. Это будет имитировать для компилятора, что переменная могла изменится в этой функции и нужно ее перечитать.
CrimsonPig
Цитата(amaora @ Aug 14 2015, 19:38) *
А я как-то обхожусь без volatile. В вашем случае можно например вызывать в цикле функцию пустышку из другого модуля. Это будет имитировать для компилятора, что переменная могла изменится в этой функции и нужно ее перечитать.


А зубы вы тоже перанально чистите ?
Функция-пустышка тоже может быть выкинута умным компилятором.
amaora
Цитата(CrimsonPig @ Aug 14 2015, 21:52) *
А зубы вы тоже перанально чистите ?
Функция-пустышка тоже может быть выкинута умным компилятором.


Если в компилируемом модуле есть только ее прототип, то не может.
zltigo
QUOTE (amaora @ Aug 18 2015, 18:59) *
Если в компилируемом модуле есть только ее прототип, то не может.

Вы отстали от жизни и Ваши представления о возможностиях компиляторов и линкеров устарели.
amaora
Цитата(zltigo @ Aug 18 2015, 19:45) *
Вы отстали от жизни и Ваши представления о возможностиях компиляторов и линкеров устарели.

Да LTO я действительно не использую.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.