|
Барьер компилятора asm volatile ("" ::: «memory») |
|
|
|
Aug 27 2014, 20:07
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Всем привет! Цитата Конструкция не содержит никаких инструкций и является барьером, говорящим компилятору: “сбрось все регистры в RAM до барьера и перечитай после”. Расскажите, пожалуйста, поконкретнее, что же делает на самом деле этот барьер помимо действий, описываемых фразой, приведенной выше. Цитата Барьеры обеспечивают надлежащий порядок доступа к volatile переменным и не обеспечивают надлежащий порядок доступа к не volatile переменным (может происходить перебрасывание через барьер). Почему? Что это значит? Код volatile x, y, z; x = 1; y = 2; z = 3; Может ли компилятор поменять порядок обращения к volatile переменным x, y, z? Т. е., влияет ли как-нибудь volatile на порядок обращения к переменным или нет? Насколько далеко может зайти компилятор, переставляя инструкции? Есть ли какая-либо взаимосвязь между барьером компилятора и точками следования?
--------------------
Благодарю заранее!
|
|
|
|
|
 |
Ответов
(1 - 11)
|
Aug 30 2014, 08:24
|

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

|
Откуда у вас такие цитаты? Насколько я знаю, обращение к volatile переменным компилятор менять не имеет права. А барьер этот используется для обеспечения порядка доступа к не-volatile переменным. Приведу пример. Код void test(){ enable_interrupts = 0; some_stuff(); enable_interrupts = 1; } enable_interrupts = volatile-регистр, отвечающий за разрешение прерываний. Без барьра компилятор делал так: Код void test(){ enable_interrupts = 0; enable_interrupts = 1; some_stuff(); } То есть, some_stuff() выполнялась при включенных прерываниях, что противоречит задумке. Введение барьера: Код void test(){ enable_interrupts = 0; some_stuff(); __asm__ __volatile__ ( :::"memory"); enable_interrupts = 1; } Решило проблему. Наверное такой барьер можно считать принудительной точкой следования, но я не берусь давать чётких определений на этот счёт.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Aug 30 2014, 11:34
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Цитата(AHTOXA @ Aug 30 2014, 12:24)  Откуда у вас такие цитаты? С форума. Цитата Насколько я знаю, обращение к volatile переменным компилятор менять не имеет права. Я тоже так думал, но, судя по всему бывают исключения... http://blog.regehr.org/archives/28Цитата and also accesses to volatiles should not be reordered (with some exceptions). http://www.nongnu.org/avr-libc/user-manual/optimization.htmlЦитата memory barriers don't ensure statements with no volatile accesses to be reordered across the barrier
--------------------
Благодарю заранее!
|
|
|
|
|
Aug 30 2014, 12:59
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Цитата(AHTOXA @ Aug 30 2014, 15:57)  Нет, менять местами обращение к volatile-переменным компилятор не имеет. Собственно, про это и написано в ссылке. То, что сделал avr-gcc в примере с cli()/sei() - может быть просто багом avr-gcc. Там еще про некоторые исключения написано  А между цитатами из первой и второй статьи вижу противоречие: Цитата Moreover, code motion is not permitted around the barrier in either direction Цитата memory barriers don't ensure statements with no volatile accesses to be reordered across the barrier Интересно, какой оверхед дает использование барьера?
Сообщение отредактировал koluna - Aug 30 2014, 13:02
--------------------
Благодарю заранее!
|
|
|
|
|
Aug 30 2014, 14:02
|

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

|
Цитата(koluna @ Aug 30 2014, 18:59)  Там еще про некоторые исключения написано  Про исключения из правила не менять порядок доступа к volatile-переменным? Не увидел. Где? Цитата(koluna @ Aug 30 2014, 18:59)  А между цитатами из первой и второй статьи вижу противоречие: Я согласен с первой цитатой. Хотя пример из avr-gcc не согласуется с ней  Цитата(koluna @ Aug 30 2014, 18:59)  Интересно, какой оверхед дает использование барьера? Если посреди развесистой функции с кучей локальных переменных, которые к моменту появления барьера уже все в регистрах, то оверхед может быть приличным.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Aug 30 2014, 22:30
|

Местный
  
Группа: Участник
Сообщений: 329
Регистрация: 23-04-14
Пользователь №: 81 502

|
Цитата(koluna @ Aug 27 2014, 21:07)  Расскажите, пожалуйста, поконкретнее, что же делает на самом деле этот барьер помимо действий, описываемых фразой, приведенной выше. Тут все просто  Надо немножко погуглить на предмет "memory barrier", "out of order execution", "cache coherency" На хабре был цикл очень хороших статей по этому поводу.. Где-то в этом районе: http://habrahabr.ru/company/ifree/blog/196548/Цитата Код volatile x, y, z; x = 1; y = 2; z = 3; Может ли компилятор поменять порядок обращения к volatile переменным x, y, z? Т. е., влияет ли как-нибудь volatile на порядок обращения к переменным или нет? Самое забавное, не в том, что компилятор может нагенерить, а то, процессор может выполнять инструкции не в том порядке, в котором они лежат в памяти..
|
|
|
|
|
Sep 1 2014, 20:09
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Цитата(CrimsonPig @ Aug 31 2014, 02:30)  Спасибо за ссылки. Вот в этой статье вижу противоречие с этой статьей (в ней есть ссылка на официальную документацию GCC): Цитата Надо отметить, что ассемблерные вставки __asm__ __volatile__ ( … ) также являются в некотором роде барьером для GCC/Clang: компилятор не имеет права ни выкидывать, ни перемещать их вверх/вниз по коду (об этом говорит модификатор __volatile__). Цитата Note that even a volatile asm instruction can be moved relative to other code, including across jump instructions. [...] Similarly, you can't expect a sequence of volatile asm instructions to remain perfectly consecutive. Видимо, в этой ситуации лучше доверять официальной документации GCC, т. е., asm volatile вставки компилятор не может выбрасывать, но может "перетаскивать" и немного оптимизировать согласно стратегии своей работы.
--------------------
Благодарю заранее!
|
|
|
|
|
Sep 2 2014, 04:21
|

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

|
Цитата(koluna @ Sep 2 2014, 02:09)  Видимо, в этой ситуации лучше доверять официальной документации GCC, т. е., asm volatile вставки компилятор не может выбрасывать, но может "перетаскивать" и немного оптимизировать согласно стратегии своей работы. Там дальше (в официальной документации) есть разъяснение, как этого избежать. (Добавить искусственную зависимость от переменной, относительно операции с которой мы не хотим, чтобы компилятор двигал asm volatile вставку. А поскольку зависимость "memory" - самая сильная (она означает зависимость от всех переменных), то, вероятно, барьер типа asm volatile (::: "memory") компилятор передвинуть никак не может.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|