О volatile замолвлю я слово

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18785
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Reflector писал(а): Программист читая регистр знает, что должно генериться прерывание, возможно именно для этого он его и читает, а без volatile результат непредсказуем...
это программист. программист всеми силами стремится в ногу не стрелять. опасность подстерегает "не совсем программиста" :) который может думать, что бессмысленное чтение ни на что не влияет.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32

Сообщение Martian »

Что-то у меня подозрение, что в мою сторону камни. Но я там был именно за понимание всего механизма работы с volatile, опциями оптимизатора, для чего, почему и как. А не за бездумное использование.
Контактная информация:
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18785
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

лично я никаких камней не кидаю.
volatile мешает оптимизатору.
помогает ли программиступисателю программ - это вопрос другой.

например, постоянно можно услышать, что все переменные, изменяемые в прерываниях, должны быть volatile... это не так. НЕ ВСЕ, а только те, которые в том нуждаются. просто надо понимать, какие нуждаются, а какие нет. если не выжимать до последнего байта всю память, то можно ставить volatile бездумно, попасть на "предсказанный" мной вариант ошибки будет редким "везением"...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32

Сообщение Martian »

Да и вообще, почему что-то быть именно должно? я вот не очень командный игрок, чаще один. Внутри команды да, есть соглашения, их все придерживаются, единый стиль, это тоже удобно. Но когда один работаю с 8-битными мк, у меня идет смесь Си с ассемблером. Ну, привычка такая, мне раньше часто доставалось от ошибок оптимизатора (да, именно его ошибок, которые впоследствии официально признавались и фиксились, а не от того, что я недоволатилил), да и мне нравится эдакое соревнование, могу ли изначально слепить оптимальный код, который оптимизатор не сможет оптимизировать.
На простых задачах это не отнимает много времени и доставляет удовольствие.
Поэтому, я против догм. Да, программист обязан знать все тонкости volatile и если глянуть на ссылку, что я приводил в той ветке и на первый пост этой ветки а так же замечаний ARV, ну никак не обойтись короткой фразой. Но применение не должно быть догмой, предложение о применении необходимо сопровождать разъяснением, почему. Потому что "оптимизатор всегда вкл" тоже не обязано быть догмой. И это мы вообще рассуждаем о фундаментальном сферическом, а вот в частном случае с частным компилятором вообще всё может быть не так. Тоже чтение регистров, например. У меня вот компилятор космика не выкидывает "пустое в никуда" неволатильное чтение регистра. Хотя, глядя на код, мне хочется его выкинуть самому.
Ну вот какая-то такая мысль. Извините, если сумбурно - малость с похмелья.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
SfS
Друг Кота
Сообщения: 19756
Зарегистрирован: Пт янв 12, 2007 11:21:39
Откуда: Томск

Сообщение SfS »

[uquote="ARV",url="/forum/viewtopic.php?p=4163233#p4163233"]volatile мешает оптимизатору.
помогает ли программиступисателю программ - это вопрос другой.[/uquote]

volatile не мешает оптимизатору. Он просто делает обращение к конкретной ячейке памяти предсказуемыми. И только.

Да, помогает. Но для этого пИсатель программ должен знать к какой ячейке надо обращаться особо (регистр там или в прерывании задействована), а какая просто ячейка, которую можно отдать на откуп оптимизатору.

Применение volatile, равно как и других инструментов, не отменяет необходимости думать головой. Это главное правило. Компилятор думать за программиста не будет.

Добавлено after 1 hour 21 minute 23 seconds:
кстати, кому не нравится volatile, то вот способ обхода. Пишите две функции (пример для байтовой ячейки) в виде отдельной библиотеки.

Код: Выделить всё

#include <stdint.h>

uint8_t getByte(void* adr) {
    return *((uint8_t*)adr);
}

void setByte(void* adr, uint8_t byte) {
    *((uint8_t*)adr) = byte;
}
Использовать соответственно:

Код: Выделить всё

a=getByte((void*)0xABCD); // Чтение из ячейки памяти с адресом 0xABCD

setByte((void*)0xABCD, 0xFE); // Запись байта 0xFE по адресу 0xABCD
Компилятор такое не оптимизирует. Но это для извратов:)
Последний раз редактировалось SfS Вт янв 18, 2022 15:54:16, всего редактировалось 1 раз.
Реклама
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="SfS",url="/forum/viewtopic.php?p=4163499#p4163499"]Компилятор такое не оптимизирует.[/uquote]
Компилятор такое и не компилирует, по крайней мере gcc :)
А если имелось в виду:

Код: Выделить всё

*((uint8_t*)adr) = byte;
то такое замечательно оптимизируется.
Реклама
SfS
Друг Кота
Сообщения: 19756
Зарегистрирован: Пт янв 12, 2007 11:21:39
Откуда: Томск

Сообщение SfS »

[uquote="Reflector",url="/forum/viewtopic.php?p=4163536#p4163536"][uquote="SfS",url="/forum/viewtopic.php?p=4163499#p4163499"]Компилятор такое не оптимизирует.[/uquote]
Компилятор такое и не компилирует, по крайней мере gcc :)[/uquote]

Замечательно комплирует. Сейчас проверил. Там почемуто амперсанды лишние из редактора копирнулись. Убрал.
Если функции делать в виде отдельной либы - то работает всё именно как задумано.

Но volatile - проще и правильней:)
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="SfS",url="/forum/viewtopic.php?p=4163572#p4163572"]Если функции делать в виде отдельной либы - то работает всё именно как задумано.[/uquote]
Проверяем, пишу:

Код: Выделить всё

setByte((void*)&GPIOB->ODR, 0x55);
setByte((void*)&GPIOB->ODR, 0xAA);
При этом setByte() находится в другом .cpp файле. Получаем вполне ожидаемый результат:

Код: Выделить всё

ldr r3, [pc, #516]
movs r2, #170	; 0xaa 
strb r2, [r3, #20]
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18785
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Reflector писал(а):Получаем вполне ожидаемый результат
LTO?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

Естественно LTO.
SfS
Друг Кота
Сообщения: 19756
Зарегистрирован: Пт янв 12, 2007 11:21:39
Откуда: Томск

Сообщение SfS »

Я в виде двух объектных файлов скомпилил тоже под арм. И там в асме прекрасно сработало.

Отдельная библиотека это вообще архив объектников. Там можно и секции лишние стрипнуть.

Добавлено after 31 second:
Другое дело, чтов реальном проекте я так делать не буду:)
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="SfS",url="/forum/viewtopic.php?p=4163499#p4163499"]кстати, кому не нравится volatile[/uquote]Чего??? Сегодня кому-то volatile не нравится, завтра const нелюб будет, а послезавтра что следующее?

Добавлено after 9 minutes 26 seconds:
[uquote="SfS",url="/forum/viewtopic.php?p=4162026#p4162026"]Адепты мантры - «а у меня и так работает» - часто нарываются на очень неожиданное поведение кода в самый неподходящий момент времени. Удачи им в скачке по граблям.[/uquote]
[uquote="SfS",url="/forum/viewtopic.php?p=4163615#p4163615"]И там в асме прекрасно сработало.[/uquote]А как дышал, как дышал :)
SfS
Друг Кота
Сообщения: 19756
Зарегистрирован: Пт янв 12, 2007 11:21:39
Откуда: Томск

Сообщение SfS »

[uquote="VladislavS",url="/forum/viewtopic.php?p=4163620#p4163620"][uquote="SfS",url="/forum/viewtopic.php?p=4163615#p4163615"]И там в асме прекрасно сработало.[/uquote]А как дышал, как дышал :)[/uquote]

А как дышал? :)
Дышал ровно и выступал за стандарты:)

Но привел пример извращения. Почему не привести ради прикола и для оживления темы? :)

Но выше товарищи правы, с lto компилерами без отключения оного lto не прокатит. А я както и не написал об этом.
Нашел транзистор. Понюхал.
Сообщения: 158
Зарегистрирован: Сб апр 24, 2021 18:42:11

Сообщение phalanx »

"Си — инструмент, острый, как бритва: с его помощью можно создать и элегантную программу, и кровавое месиво". © Керниган.
RTFM. Все остальное - на совести издателей конкретного компилятора. Дьявол всегда кроется в деталях (мелочах). Разговор ни о чем, IMHO.
SfS
Друг Кота
Сообщения: 19756
Зарегистрирован: Пт янв 12, 2007 11:21:39
Откуда: Томск

Сообщение SfS »

[uquote="phalanx",url="/forum/viewtopic.php?p=4163902#p4163902"]RTFM. Все остальное - на совести издателей конкретного компилятора.[/uquote]

Ну почему?) Используйте стандарты) Они так.. эмм.. стандартны. И работают в любом компиляторе:)
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18785
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

SfS писал(а):Они так.. эмм.. стандартны
вот именно, что "эмм"... в стандарте полно мест, которые "на усмотрение реализаторов компилятора"
к тому же мало кто видел этот стандарт на русском языке...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 6339
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

Я на AVR Си не применяю, но вот любопытная ситуация произошла. На родственном форуме у студента возникла прооблема с точками "остановки". Я по доброте душевной :) , хоть в этом и не шибко секу, посоветовал ему обратить взор на volatile - не исключено, что компилятор оптимизнул - выбросил этот бессмысленный с его точки зрения фрагмент.
СпойлерНужна помощь! При составление программы на языке С+ возникает проблема с точками остановки. Может кто подскажет что я делаю не так.
Код:
#include "compiler.h"
#include <avr/interrupt.h>
#include "conf_example.h"

// Only use Pin Change Interrupt handler for devices supporting this.
#ifdef EXAMPLE_PCINT_vect


ISR(EXAMPLE_PCINT_vect)
{

PIND = (1 << PIND0);
}

#endif


int main(void)
{

uint8_t val;

DDRD = 0xff;

// Set output levels high. Will turn off STK600 LEDs.
PORTD = 0xff;

// Set output levels low. Will turn on STK600 LEDs.
PORTD = 0;

PORTB = 0xff;

val = PINB;

while (1)
{
PORTD |= (1 << PORTD0);

PORTD &= ~(1 << PORTD0);
}
}
А мне стало интересно: как "заволатилить" порт?
Изображение
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18785
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Jack_A писал(а):как "заволатилить" порт?
порт уже заволатилен
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 6339
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

Так что моя версия - ошибочная ? А как же тогда в примере SfS (от 16.01) из-за UDR произошёл такой казус? Ведь UDR - это тоже регистр. Хотя чисто по логике, может, не в volatile дело? Загрузив байт в UDR, следовало бы дождаться флага готовности перед загрузкой следующего.
Ну а стьюденьт тоже зря лил слёзы. Загрузил в Студию hex - и всё видно, что оно там накомпиляло.
---------------
СпойлерПравильно говорит мне мой кот Мурзик: "Не занимайся фигнёй. Хочешь написать для AVR - ну ты же на асме - как на родном
:)
Изображение
SfS
Друг Кота
Сообщения: 19756
Зарегистрирован: Пт янв 12, 2007 11:21:39
Откуда: Томск

Сообщение SfS »

[uquote="Jack_A",url="/forum/viewtopic.php?p=4164658#p4164658"]Я на AVR Си не применяю, но вот любопытная ситуация произошла. На родственном форуме у студента возникла прооблема с точками "остановки". Я по доброте душевной :) , хоть в этом и не шибко секу, посоветовал ему обратить взор на volatile - не исключено, что компилятор оптимизнул - выбросил этот бессмысленный с его точки зрения фрагмент.
СпойлерНужна помощь! При составление программы на языке С+ возникает проблема с точками остановки. Может кто подскажет что я делаю не так.
Код:
#include "compiler.h"
#include <avr/interrupt.h>
#include "conf_example.h"

// Only use Pin Change Interrupt handler for devices supporting this.
#ifdef EXAMPLE_PCINT_vect


ISR(EXAMPLE_PCINT_vect)
{

PIND = (1 << PIND0);
}

#endif


int main(void)
{

uint8_t val;

DDRD = 0xff;

// Set output levels high. Will turn off STK600 LEDs.
PORTD = 0xff;

// Set output levels low. Will turn on STK600 LEDs.
PORTD = 0;

PORTB = 0xff;

val = PINB;

while (1)
{
PORTD |= (1 << PORTD0);

PORTD &= ~(1 << PORTD0);
}
}
А мне стало интересно: как "заволатилить" порт?[/uquote]

Не очень понятно о каком именно фрагменте речь.

val - обычная переменная и компилер может её выбрасить, как неиспользуемую. Всё по правилам.

PORTx и PINx - волатильные. Их не должен выбросить.

Добавлено after 2 minutes 4 seconds:
[uquote="Jack_A",url="/forum/viewtopic.php?p=4164671#p4164671"]Так что моя версия - ошибочная ? А как же тогда в примере SfS (от 16.01) из-за UDR произошёл такой казус? Ведь UDR - это тоже регистр. Хотя чисто по логике, может, не в volatile дело? Загрузив байт в UDR, следовало бы дождаться флага готовности перед загрузкой следующего.[/uquote]

Мои примеры - абстрактные - НЕ ДЛЯ AVR. И там оговорено, что UDR - это регистр записи-чтения FIFO-буфера.
Ответить

Вернуться в «Разные вопросы по МК»