Подтвердить что ты не робот

Как компиляторы С++ поддерживают атомарную С++ 11, но не поддерживают модель памяти С++ 11

При взгляде на статус внедрения Clang и g++ С++ 11 я заметил что-то странное:
они поддерживают атомы С++ 11, но они не поддерживают модель памяти С++ 11.
У меня сложилось впечатление, что у вас должна быть модель памяти С++ 11 для использования атомистики. Так в чем же разница между поддержкой атомистики и модели памяти?
Недостаток поддержки модели памяти означает, что легальные программы на С++ 11, которые используют std::atomic<T> arent seq согласованно?

ссылки:
http://clang.llvm.org/cxx_status.html
http://gcc.gnu.org/gcc-4.7/cxx0x_status.html

4b9b3361

Ответ 1

Одной из проблем является определение "местоположения памяти", которое позволяет (и заставляет компилятор поддерживать) блокировать разные элементы структуры различными блокировками. Существует обсуждение проблемы RL, вызванной этим.

В основном проблема заключается в том, что наличие struct определяется следующим образом:

struct x {
    long a;
    unsigned int b1;
    unsigned int b2:1;
};

компилятор может свободно записывать на b2, переписывая b1 тоже (и, судя по отчету, он делает это). Поэтому два поля должны быть заблокированы как одно. Однако, как следствие модели памяти С++ 11, это запрещено (ну, на самом деле, это не запрещено, но компилятор должен обеспечить одновременное обновление b1 и b2, не вмешиваясь, он может сделать это путем блокировки или CAS-ing каждое такое обновление, ну, на некоторых архитектурах сложно жить). Цитирование из отчета:

Я поднял вопрос с нашими парнями GCC, и они сказали мне, что: "C делает не предоставляют такую ​​гарантию, и вы не можете надежно заблокировать разные структурированные поля с различными замками, если они разделены естественным образом области памяти размера слова. Модель памяти С++ 11 гарантировала бы это, но это не реализовано, и вы не создаете ядро ​​с помощью С++ 11 компилятор".

Приятную информацию можно найти в wiki.

Ответ 2

Я думаю, что "Недостаток модели памяти" в этих случаях просто означает, что оптимизаторы были написаны до публикации модели памяти С++ 11 и могут выполнять теперь недействительные оптимизации. Очень сложно и трудоемко проверять оптимизацию по сравнению с моделью памяти, поэтому не удивительно, что команды clang/gcc еще не закончили это.

Оказывает ли недостаток поддержки модели памяти, что законные программы на С++ 11, которые используют std:: atomic arent seq?

Да, это возможность. Это еще хуже: компилятор может вводить ракеты данных в (в соответствии со стандартами С++ 11) без гонок, например. путем введения спекулятивных записей.

Например, несколько компиляторов С++ использовали эту оптимизацию:

for (p = q; p = p -> next; ++p) {
    if (p -> data > 0) ++count;
}

Можно оптимизировать:

register int r1 = count;
for (p = q; p = p -> next; ++p) {
    if (p -> data > 0) ++r1;
}
count = r1;

Если все p->data неотрицательны, исходный код не записывался в count, но оптимизированный код делает. Это может привести к гонке данных в другой программе без гонок, поэтому спецификация С++ 11 запрещает такую ​​оптимизацию. Существующие компиляторы теперь должны проверять (и при необходимости корректировать) все оптимизации.

Подробнее см. Concurrency последствия компилятора модели памяти.

Ответ 3

Это не так, что они не поддерживают модель памяти, но что они еще не поддерживают API в стандарте для взаимодействия с моделью памяти. Этот API включает в себя несколько мьютексов.

Тем не менее, как Clang, так и GCC были как можно более осведомлены о потоке без формального стандарта в течение некоторого времени. Вам не нужно беспокоиться о том, что оптимизация перемещает объекты в неправильную сторону атомных операций.