Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Барьер компилятора asm volatile ("" ::: «memory»)
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
koluna
Всем привет!

Цитата
Конструкция не содержит никаких инструкций и является барьером, говорящим компилятору: “сбрось все регистры в RAM до барьера и перечитай после”.


Расскажите, пожалуйста, поконкретнее, что же делает на самом деле этот барьер помимо действий, описываемых фразой, приведенной выше.

Цитата
Барьеры обеспечивают надлежащий порядок доступа к volatile переменным и не обеспечивают надлежащий порядок доступа к не volatile переменным (может происходить перебрасывание через барьер).


Почему? Что это значит?

Код
volatile x, y, z;
x = 1;
y = 2;
z = 3;

Может ли компилятор поменять порядок обращения к volatile переменным x, y, z?
Т. е., влияет ли как-нибудь volatile на порядок обращения к переменным или нет?
Насколько далеко может зайти компилятор, переставляя инструкции?

Есть ли какая-либо взаимосвязь между барьером компилятора и точками следования?
koluna
Ребят, кто-нибудь поделится знаниями? sm.gif
AHTOXA
Откуда у вас такие цитаты?
Насколько я знаю, обращение к 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;
}

Решило проблему.
Наверное такой барьер можно считать принудительной точкой следования, но я не берусь давать чётких определений на этот счёт.
koluna
Цитата(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


AHTOXA
Цитата(koluna @ Aug 30 2014, 17:34) *
Я тоже так думал, но, судя по всему бывают исключения...

Нет, менять местами обращение к volatile-переменным компилятор не имеет. Собственно, про это и написано в ссылке.
То, что сделал avr-gcc в примере с cli()/sei() - может быть просто багом avr-gcc.
koluna
Цитата(AHTOXA @ Aug 30 2014, 15:57) *
Нет, менять местами обращение к volatile-переменным компилятор не имеет. Собственно, про это и написано в ссылке.
То, что сделал avr-gcc в примере с cli()/sei() - может быть просто багом avr-gcc.


Там еще про некоторые исключения написано sm.gif

А между цитатами из первой и второй статьи вижу противоречие:

Цитата
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


Интересно, какой оверхед дает использование барьера?
AHTOXA
Цитата(koluna @ Aug 30 2014, 18:59) *
Там еще про некоторые исключения написано sm.gif

Про исключения из правила не менять порядок доступа к volatile-переменным? Не увидел. Где?
Цитата(koluna @ Aug 30 2014, 18:59) *
А между цитатами из первой и второй статьи вижу противоречие:

Я согласен с первой цитатой. Хотя пример из avr-gcc не согласуется с нейsm.gif
Цитата(koluna @ Aug 30 2014, 18:59) *
Интересно, какой оверхед дает использование барьера?

Если посреди развесистой функции с кучей локальных переменных, которые к моменту появления барьера уже все в регистрах, то оверхед может быть приличным.
CrimsonPig
Цитата(koluna @ Aug 27 2014, 21:07) *
Расскажите, пожалуйста, поконкретнее, что же делает на самом деле этот барьер помимо действий, описываемых фразой, приведенной выше.


Тут все просто sm.gif Надо немножко погуглить на предмет "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 на порядок обращения к переменным или нет?


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

yes
если отвлечься от армовской (?) архитектуры, то это _compiler_barrier, а бывают еще _machine_barrier (в спарке v8 он например вставляет flush), то есть можно почитать для SPARC-а про формализацию моделей памяти TSO, PSO и т.д.
у современных х86 тоже должно быть интересно, но я не в теме
koluna
Цитата(CrimsonPig @ Aug 31 2014, 02:30) *
Самое забавное, не в том, что компилятор может нагенерить, а то, процессор может выполнять инструкции не в том порядке, в котором они лежат в памяти..


Это я знаю, но в данный момент меня интересуют более простые ситуации sm.gif

В данный момент обсуждаем именно барьер компилятора.
koluna
Цитата(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 вставки компилятор не может выбрасывать, но может "перетаскивать" и немного оптимизировать согласно стратегии своей работы.
AHTOXA
Цитата(koluna @ Sep 2 2014, 02:09) *
Видимо, в этой ситуации лучше доверять официальной документации GCC, т. е., asm volatile вставки компилятор не может выбрасывать, но может "перетаскивать" и немного оптимизировать согласно стратегии своей работы.

Там дальше (в официальной документации) есть разъяснение, как этого избежать. (Добавить искусственную зависимость от переменной, относительно операции с которой мы не хотим, чтобы компилятор двигал asm volatile вставку.
А поскольку зависимость "memory" - самая сильная (она означает зависимость от всех переменных), то, вероятно, барьер типа asm volatile (::: "memory") компилятор передвинуть никак не может.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.