Перейти к содержанию
    

Очевидно что Вы и читать исходники не умеете.
А Вы убеждать не умеете. Использование одного и того же байта-флага в разных прерываниях описали, хорошо, но конкретной причины для дальнейшего сбоя по прежнему нет.

 

1) если переменная используется в двух потоках (читай - в основном цикле и прерывании). Компилятор обязан при каждом обращении на чтение вычитывать ее из ОЗУ и при каждом обращении на запись класть обратно.
По идее так должно быть, но не обязательно же?

Просто скорость реакции уменьшится (обновленные данные внешней операцией будут получены при повторном чтении переменной).

 

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

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А если я работаю с переменной через указатель на неё, то что?

Я должен такую переменную объявлять как волатайл?

Ведь компилятор не может проследить все случаи где я получаю доступ к переменной через указатель на неё

Попробуйте как-нить написать:

c = *p;

...//пара операций

if (*p) ...

увидите что при наличии оптимизации, компилятор часто не будет делать второе чтение из памяти, а использует копию переменной в регистре, ранее прочитанную.

Он не знает и не должен знать, что Вы возможно в параллельной задаче ОС или ISR можете её изменить. Об этом должен думать программист.

Тем более если такое написано в теле цикла - компилятор тем более *p считает в регистр и всё время цикла будет её там хранить.

А вот уже если в этом теле цикла вы сделаете *p++, то тут поведение компилятора различно: если в этом цикле нет обращений через указатели к памяти, и стоит оптимизация "по скорости" то скорей всего он и модификацию выполнит в регистре, а сохранение в память - уже после выхода из цикла.

Если же обращения есть, то может сделать и так и так - в зависимости от компилятора от степени оптимизации.

К тому же в некоторых компиляторах для указателей можно задавать специальные модификаторы, говорящие что работа с данными через них не имеет "side effects", т.е. - что указатель указывает на свои отдельные данные, которые никак не пересекаются с данными других указателей и областями хранения переменных используемых в этой функции.

Это позволяет компилятору выполнять оптимизацию работы с этими указателями по-максимуму, например: загрузка данных из области этих указателей может выполняться заранее

(например в коде есть несколько обращений: p[1], p[2], p[3],... размазанных по циклу, компилятор может загрузить эти данные сразу в одном месте или даже вообще до входа в цикл или загружать данные для следующего прохода цикла в предыдущем проходе, менять кол-во проховдов цикла, частично или полностью разворачивать его, делая предварительную загрузку, а сохранение в такие указатели вообще - в последующих проходах цикла).

Это позволяет конвееризировать обработку данных, что очень ярко видно на процессорах, умеющих распараллеливать вычисления в несколько потоков, имеющих несколько АЛУ, например - DSP. DSP-шные оптимизаторы выполняют как правило такое преобразование кода, которое и не снилось на ARM-системах. Так как там в разы больше регистров и способов адресации памяти.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет. Компилятор вещь достаточно умная - он понимает что такое указатель и к чему может привести взятие адреса переменной (для этой переменной)

Вы не читатель?

Так я повторю:

Причем используют неявно. Без использования операции "взятие адреса" (амперсанд)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы не читатель?

Так я повторю:

Сама переменная должна объявляться как волатАЙл если её используют через указатель?

Причем используют неявно. Без использования операции "взятие адреса" (амперсанд)

Так не бывает :)

Приведите пример.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы ошибаетесь.

Просто я не хочу обсуждать вкус устриц с человеком, который устрицу не отличает от камбалы.

Простите.

Просто Вы своим вопросом показали, что вы ещё бОльший нуб в программировании чем я.

Поэтому чего я у вас буду чего-то спрашивать?

Изменено пользователем Укушенный воблой

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я не против 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы ошибаетесь.

Просто я не хочу обсуждать вкус устриц с человеком, который устрицу не отличает от камбалы.

Вы своим ответом показали, что вы все же хам, причем необразованный. Ляпнули какую то глупость, на просьбу привести пример - не привели, в оскорбили собеседника.

 

Поэтому чего я у вас буду чего-то спрашивать?
Это я у вас спрашивал. Не в состоянии ответить - не отвечайте, оскорблять зачем?

 

Просто я не хочу обсуждать вкус устриц с человеком, который устрицу не отличает от камбалы.
Это уже прямое оскорбление. Откуда вам знать мой уровень?

 

Вы форум смортели, прежде чем на человека наезжать?

 

Требую публичного извенения.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

res_yes_volatile = tick*tick; // 2*2 = 6

Здесь компилятор вроде как должен выдать варнинг. Значит так лучше не писать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здесь компилятор вроде как должен выдать варнинг. Значит так лучше не писать.

Да, забыл добавить. Компилятор выдает варнинг:

"undefined behavior: the order of volatile accesses is undefined in this statement"

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Требую публичного извенения.

Ну вы нашли, с кем схлестнуться. Это же, судя по всему, Доктор ТуамОсес, он же Дон Амброзио, он же avr123, он же [ещё куча ников]. Это известный тролль, не тратьте на него своё время и нервы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну вы нашли, с кем схлестнуться. Это же, судя по всему, Доктор ТуамОсес, он же Дон Амброзио, он же avr123, он же [ещё куча ников]. Это известный тролль, не тратьте на него своё время и нервы.

Да, это именно этот персонаж.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2. второй оператор умножения в цикле компилятор просто выбросил за ненадобностью.

Выключите оптимизацию в опциях компилятора

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...