Alt.F4 2 19 января, 2017 Опубликовано 19 января, 2017 · Жалоба Очевидно что Вы и читать исходники не умеете.А Вы убеждать не умеете. Использование одного и того же байта-флага в разных прерываниях описали, хорошо, но конкретной причины для дальнейшего сбоя по прежнему нет. 1) если переменная используется в двух потоках (читай - в основном цикле и прерывании). Компилятор обязан при каждом обращении на чтение вычитывать ее из ОЗУ и при каждом обращении на запись класть обратно.По идее так должно быть, но не обязательно же? Просто скорость реакции уменьшится (обновленные данные внешней операцией будут получены при повторном чтении переменной). Я не против volatile, просто хочется понять, когда без него ну совсем не обойтись и код точно не будет работать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 172 19 января, 2017 Опубликовано 19 января, 2017 · Жалоба А если я работаю с переменной через указатель на неё, то что? Я должен такую переменную объявлять как волатайл? Ведь компилятор не может проследить все случаи где я получаю доступ к переменной через указатель на неё Попробуйте как-нить написать: c = *p; ...//пара операций if (*p) ... увидите что при наличии оптимизации, компилятор часто не будет делать второе чтение из памяти, а использует копию переменной в регистре, ранее прочитанную. Он не знает и не должен знать, что Вы возможно в параллельной задаче ОС или ISR можете её изменить. Об этом должен думать программист. Тем более если такое написано в теле цикла - компилятор тем более *p считает в регистр и всё время цикла будет её там хранить. А вот уже если в этом теле цикла вы сделаете *p++, то тут поведение компилятора различно: если в этом цикле нет обращений через указатели к памяти, и стоит оптимизация "по скорости" то скорей всего он и модификацию выполнит в регистре, а сохранение в память - уже после выхода из цикла. Если же обращения есть, то может сделать и так и так - в зависимости от компилятора от степени оптимизации. К тому же в некоторых компиляторах для указателей можно задавать специальные модификаторы, говорящие что работа с данными через них не имеет "side effects", т.е. - что указатель указывает на свои отдельные данные, которые никак не пересекаются с данными других указателей и областями хранения переменных используемых в этой функции. Это позволяет компилятору выполнять оптимизацию работы с этими указателями по-максимуму, например: загрузка данных из области этих указателей может выполняться заранее (например в коде есть несколько обращений: p[1], p[2], p[3],... размазанных по циклу, компилятор может загрузить эти данные сразу в одном месте или даже вообще до входа в цикл или загружать данные для следующего прохода цикла в предыдущем проходе, менять кол-во проховдов цикла, частично или полностью разворачивать его, делая предварительную загрузку, а сохранение в такие указатели вообще - в последующих проходах цикла). Это позволяет конвееризировать обработку данных, что очень ярко видно на процессорах, умеющих распараллеливать вычисления в несколько потоков, имеющих несколько АЛУ, например - DSP. DSP-шные оптимизаторы выполняют как правило такое преобразование кода, которое и не снилось на ARM-системах. Так как там в разы больше регистров и способов адресации памяти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Укушенный воблой 0 19 января, 2017 Опубликовано 19 января, 2017 · Жалоба Нет. Компилятор вещь достаточно умная - он понимает что такое указатель и к чему может привести взятие адреса переменной (для этой переменной) Вы не читатель? Так я повторю: Причем используют неявно. Без использования операции "взятие адреса" (амперсанд) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 19 января, 2017 Опубликовано 19 января, 2017 · Жалоба Вы не читатель? Так я повторю: Сама переменная должна объявляться как волатАЙл если её используют через указатель? Причем используют неявно. Без использования операции "взятие адреса" (амперсанд) Так не бывает :) Приведите пример. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Укушенный воблой 0 19 января, 2017 Опубликовано 19 января, 2017 · Жалоба Так не бывает :) Зачем? С Вами и так все ясно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 19 января, 2017 Опубликовано 19 января, 2017 · Жалоба Зачем? С Вами и так все ясно. А вы батенька хам и троль. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Укушенный воблой 0 19 января, 2017 Опубликовано 19 января, 2017 (изменено) · Жалоба Вы ошибаетесь. Просто я не хочу обсуждать вкус устриц с человеком, который устрицу не отличает от камбалы. Простите. Просто Вы своим вопросом показали, что вы ещё бОльший нуб в программировании чем я. Поэтому чего я у вас буду чего-то спрашивать? Изменено 19 января, 2017 пользователем Укушенный воблой Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 20 января, 2017 Опубликовано 20 января, 2017 (изменено) · Жалоба Я не против 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 Изменено 20 января, 2017 пользователем aiwa Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 20 января, 2017 Опубликовано 20 января, 2017 · Жалоба Вы ошибаетесь. Просто я не хочу обсуждать вкус устриц с человеком, который устрицу не отличает от камбалы. Вы своим ответом показали, что вы все же хам, причем необразованный. Ляпнули какую то глупость, на просьбу привести пример - не привели, в оскорбили собеседника. Поэтому чего я у вас буду чего-то спрашивать?Это я у вас спрашивал. Не в состоянии ответить - не отвечайте, оскорблять зачем? Просто я не хочу обсуждать вкус устриц с человеком, который устрицу не отличает от камбалы.Это уже прямое оскорбление. Откуда вам знать мой уровень? Вы форум смортели, прежде чем на человека наезжать? Требую публичного извенения. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 20 января, 2017 Опубликовано 20 января, 2017 · Жалоба Побейтесь еще за пустой мешок! :w00t: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 172 20 января, 2017 Опубликовано 20 января, 2017 · Жалоба res_yes_volatile = tick*tick; // 2*2 = 6 Здесь компилятор вроде как должен выдать варнинг. Значит так лучше не писать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 20 января, 2017 Опубликовано 20 января, 2017 · Жалоба Здесь компилятор вроде как должен выдать варнинг. Значит так лучше не писать. Да, забыл добавить. Компилятор выдает варнинг: "undefined behavior: the order of volatile accesses is undefined in this statement" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 20 января, 2017 Опубликовано 20 января, 2017 · Жалоба Требую публичного извенения. Ну вы нашли, с кем схлестнуться. Это же, судя по всему, Доктор ТуамОсес, он же Дон Амброзио, он же avr123, он же [ещё куча ников]. Это известный тролль, не тратьте на него своё время и нервы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 20 января, 2017 Опубликовано 20 января, 2017 · Жалоба Ну вы нашли, с кем схлестнуться. Это же, судя по всему, Доктор ТуамОсес, он же Дон Амброзио, он же avr123, он же [ещё куча ников]. Это известный тролль, не тратьте на него своё время и нервы. Да, это именно этот персонаж. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Укушенный воблой 0 21 января, 2017 Опубликовано 21 января, 2017 · Жалоба 2. второй оператор умножения в цикле компилятор просто выбросил за ненадобностью. Выключите оптимизацию в опциях компилятора Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться