Должны ли C90-совместимые компиляторы учитывать переупорядочение команд процессором? - PullRequest
4 голосов
/ 27 декабря 2011

Рассмотрим следующий фрагмент кода:

volatile int a;
volatile int b;
int x;

void func() {
    a = 1;
    x = 0; /* dummy statement */
    b = 2;
}

В этом фрагменте кода назначение x представляет собой точку последовательности.Следовательно, согласно стандарту C90, доступ к энергозависимой переменной a должен быть завершен до того, как начнется доступ к b.При переводе этого фрагмента кода на ассемблер x86-64 тело функции переводится следующим образом:

movl $1, a(%rip)
movl $0, x(%rip)
movl $2, b(%rip)

Теперь при выполнении этого кода ЦП может изменить порядок доступа к памяти, тем самым нарушая требованиестандарта C, что доступ к a и b выполняется по порядку.Итак, не является ли этот перевод неправильным, и не нужно ли компилятору вставлять барьеры памяти для обеспечения порядка?

Редактировать: Рассмотрим случай, когда a и b являются переменными, общими для двух потоков.В этом случае протокол синхронизации между двумя потоками может опираться на тот факт, что доступ к a и b происходит по порядку.Таким образом, когда ЦП переупорядочивает доступ, это может нарушить этот протокол (на самом деле я не пытаюсь реализовать такой протокол, мне просто интересно, какова правильная интерпретация стандарта C).

1 Ответ

6 голосов
/ 27 декабря 2011

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

...