Атомарный доступ к неатомной памяти в C++11 и OpenMP?

OpenMP, в отличие от C++11, работает с атомарностью с точки зрения операций памяти, а не переменных. Это позволяет, например, использовать атомарные чтения / записи для целых чисел, хранящихся в векторе с неизвестным размером во время компиляции:

std::vector<int> v;

// non-atomic access (e.g., in a sequential region):
v.resize(n);
...
v.push_back(i);
...

// atomic access in a multi-threaded region:
#pragma omp atomic write // seq_cst
v[k] = ...;
#pragma omp atomic read // seq_cst
... = v[k];

В C++11 это невозможно достичь. Мы можем получить доступ к атомарным переменным как неатомным, расслабляя модель памяти, но мы не можем изменить размер вектора атомарных элементов.

Я понимаю, что есть причины, почему c++ не позволяет получить доступ к неатомным переменным с помощью операций атомной памяти. Но мне интересно, почему эти причины не относятся и к OpenMP.

например,N4013, говорят, что " нет разумного способа полностью переносимо применять атомарные операции к данным, не объявленным атомарными." как возможно, что OpenMP может гарантировать такую переносимость, а C++ нет?

1 ответов


насколько я понимаю соответствующие стандарты, OpenMP имеет больше ограничений на использование, чем C++11, что позволяет ему быть портативным без использования специальных типов. Например, OpenMP 4.5 говорит:

Если место хранения, обозначенное x, не выровнено по размеру (то есть если выравнивание байтов x не кратно размеру x), то поведение атомной области определяется реализацией.

С другой стороны, если C++11 использует std::atomic<int>, затем компилятор гарантирует соответствующее выравнивание. В обоих случаях требуется выравнивание, но OpenMP и C++11 отличаются тем, кто отвечает за обеспечение этого.

Как правило, существуют философские различия между OpenMP и C++, но их трудно перечислить все. Люди C++ думают о переносимости ко всему, в то время как OpenMP нацелен на HPC.