Почему не поддерживается атомарная директива OpenMP? - PullRequest
4 голосов
/ 28 сентября 2010

Директива atomic в openmp поддерживает такие вещи, как

x += expr
x *= expr

, где expr - это выражение скалярного типа, которое не ссылается на x.Я понимаю, но я не понимаю, почему вы не можете сделать:

#pragma omp atomic
x = y;

Это как-то более обременительно с точки зрения инструкций процессора?Мне кажется, что как допустимое, так и недопустимое утверждение загружает значение x и некоторое другое скалярное значение, изменяет значение регистра x и записывает его обратно.Если бы кто-нибудь мог объяснить мне, как эти инструкции (я предполагаю) принципиально отличаются, я был бы очень благодарен.

1 Ответ

0 голосов
/ 06 октября 2010

Потому что предложенное атомарное назначение не защищает от чего-либо.

Помните, что атомарную инструкцию можно рассматривать как критическую секцию, которая может (но не обязательно) быть эффективно реализована компилятором с использованием магического оборудования.Подумайте о двух потоках, достигающих x = y с общим x и приватным y.После завершения всех потоков x равен последнему потоку, выполнившему "winins", и устанавливает x в y.Оберните назначение в критическом разделе, и ничего не изменится, последний поток все еще "выигрывает".Теперь, если потоки делают что-то еще с x, впоследствии самый медленный поток, возможно, не догнал, и даже если у него есть компилятор, он может законно использовать выбор для некоторого кэшированного значения для x (то есть локальное y потока).Чтобы избежать этого, вам понадобится барьер (чтобы победившая нить выиграла) и подразумеваемый сброс (так что локальный кэш был признан недействительным):

x = y;
#pragma omp barrier
\\ do something with shared x...

, но я не могу найти вескую причину для этогоэтот.Зачем вся работа по поиску y во многих потоках, если большинство из них будет (недетерминировано) выброшено?

...