Информация об изменениях

Сообщение Re[4]: Что именно делают /volatile:ms и /volatile:iso на x86 от 06.01.2022 11:21

Изменено 06.01.2022 11:24 netch80

Re[4]: Что именно делают /volatile:ms и /volatile:iso на x86 ?
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>>>поскольку компилятор ничего не обещает в плане атомарности.

AG>>Платформа обещает
ЕМ>Это лишь о чтении/записи, и только выровненных данных в пределах ширины магистрали. Разве такие операции не везде атомарны? Даже представить не могу, для чего могло бы потребоваться выполнять их иначе, чем за один цикл.

Ну вот пример: у тебя есть структура вида

struct moo {
  unsigned a: 31;
  unsigned b: 5;
  unsigned c: 22;
  unsigned d: 6;
  unsigned e: 16;
} __attribute__((packed));


Посмотри, как твой компилятор делает чтение поля b. Он его сложно собирает из частей. Возможно, это байты. Это ещё понятно. А что будет с полем e? Его соберёт или нет? Оно ведь чётко 2 байта на границе 2 байт, почему бы и нет?
Я закинул код чтения двух полей на godbolt и начал смотреть разные компиляторы. И опаньки — clang для x86 нормально читает двухбайтное значение чтением по word ptr, а вот для RV32 почему-то начал побайтно извлекать:

get_e:                                  # @get_e
        lbu     a1, 9(a0)
        lbu     a0, 8(a0)
        slli    a1, a1, 8
        or      a0, a0, a1
        ret


Аааа за что, дяденьки? Он же мог простейший lhu применить...

Видишь — чуть-чуть замаскировали и компилятор уже не понимает, что ему надо было делать.

AG>>Через __iso_volatile_load64 / __iso_volatile_store64 можно атомарно загрузить-сохранить 64-битную переменную в 32-битном x86


ЕМ>Это уже откровенное извращение через XMM.


Почему, если XMM декларирован доступным?
Re[4]: Что именно делают /volatile:ms и /volatile:iso на x86
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>>>поскольку компилятор ничего не обещает в плане атомарности.

AG>>Платформа обещает
ЕМ>Это лишь о чтении/записи, и только выровненных данных в пределах ширины магистрали. Разве такие операции не везде атомарны? Даже представить не могу, для чего могло бы потребоваться выполнять их иначе, чем за один цикл.

Ну вот пример: у тебя есть структура вида

struct moo {
  unsigned a: 31;
  unsigned b: 5;
  unsigned c: 22;
  unsigned d: 6;
  unsigned e: 16;
} __attribute__((packed));


Посмотри, как твой компилятор делает чтение поля b. Он его сложно собирает из частей. Возможно, это байты. Это ещё понятно. А что будет с полем e? Его соберёт или нет? Оно ведь чётко 2 байта на границе 2 байт, почему бы и нет?
Я закинул код чтения двух полей на godbolt и начал смотреть разные компиляторы. И опаньки — clang для x86 нормально читает двухбайтное значение чтением по word ptr, а вот для RV32 почему-то начал побайтно извлекать:

get_e:                                  # @get_e
        lbu     a1, 9(a0)
        lbu     a0, 8(a0)
        slli    a1, a1, 8
        or      a0, a0, a1
        ret


Аааа за что, дяденьки? Он же мог простейший lhu применить...

Видишь — чуть-чуть замаскировали и компилятор уже не понимает, что ему надо было делать.

(Ну да, если ты заточен на одну платформу и один компилятор, тебе пофиг. Мне не так.)

AG>>Через __iso_volatile_load64 / __iso_volatile_store64 можно атомарно загрузить-сохранить 64-битную переменную в 32-битном x86


ЕМ>Это уже откровенное извращение через XMM.


Почему, если XMM декларирован доступным?