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