|
|
  |
Вопрос по volatile |
|
|
|
Jan 19 2017, 07:32
|
Профессионал
    
Группа: Свой
Сообщений: 1 468
Регистрация: 28-03-10
Из: Беларусь
Пользователь №: 56 256

|
Цитата Очевидно что Вы и читать исходники не умеете. А Вы убеждать не умеете. Использование одного и того же байта-флага в разных прерываниях описали, хорошо, но конкретной причины для дальнейшего сбоя по прежнему нет. Цитата 1) если переменная используется в двух потоках (читай - в основном цикле и прерывании). Компилятор обязан при каждом обращении на чтение вычитывать ее из ОЗУ и при каждом обращении на запись класть обратно. По идее так должно быть, но не обязательно же? Просто скорость реакции уменьшится (обновленные данные внешней операцией будут получены при повторном чтении переменной). Я не против volatile, просто хочется понять, когда без него ну совсем не обойтись и код точно не будет работать.
|
|
|
|
|
Jan 19 2017, 07:37
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Укушенный воблой @ Jan 18 2017, 21:31)  А если я работаю с переменной через указатель на неё, то что? Я должен такую переменную объявлять как волатайл? Ведь компилятор не может проследить все случаи где я получаю доступ к переменной через указатель на неё Попробуйте как-нить написать: c = *p; ...//пара операций if (*p) ... увидите что при наличии оптимизации, компилятор часто не будет делать второе чтение из памяти, а использует копию переменной в регистре, ранее прочитанную. Он не знает и не должен знать, что Вы возможно в параллельной задаче ОС или ISR можете её изменить. Об этом должен думать программист. Тем более если такое написано в теле цикла - компилятор тем более *p считает в регистр и всё время цикла будет её там хранить. А вот уже если в этом теле цикла вы сделаете *p++, то тут поведение компилятора различно: если в этом цикле нет обращений через указатели к памяти, и стоит оптимизация "по скорости" то скорей всего он и модификацию выполнит в регистре, а сохранение в память - уже после выхода из цикла. Если же обращения есть, то может сделать и так и так - в зависимости от компилятора от степени оптимизации. К тому же в некоторых компиляторах для указателей можно задавать специальные модификаторы, говорящие что работа с данными через них не имеет "side effects", т.е. - что указатель указывает на свои отдельные данные, которые никак не пересекаются с данными других указателей и областями хранения переменных используемых в этой функции. Это позволяет компилятору выполнять оптимизацию работы с этими указателями по-максимуму, например: загрузка данных из области этих указателей может выполняться заранее (например в коде есть несколько обращений: p[1], p[2], p[3],... размазанных по циклу, компилятор может загрузить эти данные сразу в одном месте или даже вообще до входа в цикл или загружать данные для следующего прохода цикла в предыдущем проходе, менять кол-во проховдов цикла, частично или полностью разворачивать его, делая предварительную загрузку, а сохранение в такие указатели вообще - в последующих проходах цикла). Это позволяет конвееризировать обработку данных, что очень ярко видно на процессорах, умеющих распараллеливать вычисления в несколько потоков, имеющих несколько АЛУ, например - DSP. DSP-шные оптимизаторы выполняют как правило такое преобразование кода, которое и не снилось на ARM-системах. Так как там в разы больше регистров и способов адресации памяти.
|
|
|
|
|
Jan 19 2017, 17:24
|
Частый гость
 
Группа: Участник
Сообщений: 197
Регистрация: 8-07-16
Пользователь №: 92 484

|
Цитата(XVR @ Jan 19 2017, 06:34)  Нет. Компилятор вещь достаточно умная - он понимает что такое указатель и к чему может привести взятие адреса переменной (для этой переменной) Вы не читатель? Так я повторю: Цитата(Укушенный воблой @ Jan 19 2017, 04:18)  Причем используют неявно. Без использования операции "взятие адреса" (амперсанд)
|
|
|
|
|
Jan 19 2017, 19:42
|
Частый гость
 
Группа: Участник
Сообщений: 197
Регистрация: 8-07-16
Пользователь №: 92 484

|
Цитата(XVR @ Jan 19 2017, 20:21)  Так не бывает  Зачем? С Вами и так все ясно.
|
|
|
|
|
Jan 20 2017, 04:17
|
Местный
  
Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682

|
Цитата(Alt.F4 @ Jan 19 2017, 09:32)  Я не против volatile, просто хочется понять, когда без него ну совсем не обойтись и код точно не будет работать. Ожидание готовности периферии - sp, twi, usart и прочее. Регистры, содержащие флаги объявлены как volatile: в противном случае неизбежно зацикливание. Но у volatile есть и обратная сторона: использовать их нужно через не-volatile копии. Совершенно искуственный, но показательный пример: Код volatile unsigned char tick = 1; volatile unsigned char res_yes_volatile=0; unsigned char res_no_volatile=0; unsigned char flag=0;
__irq void IRQ_Handler(void) { tick++; flag = tick; }
int main() { while(flag < 6) { res_yes_volatile = tick*tick; // 2*2 = 6 res_no_volatile = tick*tick; } return 0; } Имеем в итоге: 1. вечный цикл из-за того, что flag не объявлена как volatile. 2. второй оператор умножения в цикле компилятор просто выбросил за ненадобностью. 3. команды для первого оператора цикла компилятор добросовестно сгенерировал, но так как volatile-ный tick использован напрямую, без посредников, возможны коллизии типа 2*2 = 6, 5*5 = 30. Код // 16 int main() // 17 // 18 { main: LDR.N R0,??DataTable1 // 19 // 20 // 21 while(flag < 6) LDRB R1,[R0, #+3] CMP R1,#+6 BGE.N ??main_0 // 22 { // 23 res_yes_volatile = tick*tick; ??main_1: LDRB R1,[R0, #+0] LDRB R2,[R0, #+0] MULS R1,R2,R1 STRB R1,[R0, #+1] // 24 res_no_volatile = tick*tick; LDRB R1,[R0, #+0] LDRB R1,[R0, #+0] B.N ??main_1 // 25 } // 26 // 27 return 0; ??main_0: MOVS R0,#+0 BX LR ;; return
Сообщение отредактировал aiwa - Jan 20 2017, 04:18
|
|
|
|
|
Jan 20 2017, 09:40
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(Укушенный воблой @ Jan 19 2017, 23:30)  Вы ошибаетесь. Просто я не хочу обсуждать вкус устриц с человеком, который устрицу не отличает от камбалы. Вы своим ответом показали, что вы все же хам, причем необразованный. Ляпнули какую то глупость, на просьбу привести пример - не привели, в оскорбили собеседника. Цитата Поэтому чего я у вас буду чего-то спрашивать? Это я у вас спрашивал. Не в состоянии ответить - не отвечайте, оскорблять зачем? Цитата Просто я не хочу обсуждать вкус устриц с человеком, который устрицу не отличает от камбалы. Это уже прямое оскорбление. Откуда вам знать мой уровень? Вы форум смортели, прежде чем на человека наезжать? Требую публичного извенения.
|
|
|
|
|
Jan 20 2017, 10:28
|
Местный
  
Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682

|
Цитата(jcxz @ Jan 20 2017, 12:03)  Здесь компилятор вроде как должен выдать варнинг. Значит так лучше не писать. Да, забыл добавить. Компилятор выдает варнинг: "undefined behavior: the order of volatile accesses is undefined in this statement"
|
|
|
|
|
Jan 20 2017, 11:19
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(XVR @ Jan 20 2017, 14:40)  Требую публичного извенения. Ну вы нашли, с кем схлестнуться. Это же, судя по всему, Доктор ТуамОсес, он же Дон Амброзио, он же avr123, он же [ещё куча ников]. Это известный тролль, не тратьте на него своё время и нервы.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jan 20 2017, 20:21
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(AHTOXA @ Jan 20 2017, 13:19)  Ну вы нашли, с кем схлестнуться. Это же, судя по всему, Доктор ТуамОсес, он же Дон Амброзио, он же avr123, он же [ещё куча ников]. Это известный тролль, не тратьте на него своё время и нервы. Да, это именно этот персонаж.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 21 2017, 09:09
|
Частый гость
 
Группа: Участник
Сообщений: 197
Регистрация: 8-07-16
Пользователь №: 92 484

|
Цитата(aiwa @ Jan 20 2017, 05:17)  2. второй оператор умножения в цикле компилятор просто выбросил за ненадобностью. Выключите оптимизацию в опциях компилятора
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|