Нужен ли атом #pragma omp для одновременной установки флага? - PullRequest
1 голос
/ 27 апреля 2019

В программе на C, использующей OpenMP, я хочу установить флаг, когда какой-либо поток (мне не нужно знать, какой) отвечает условию.Если переменная флага является общей для всех потоков, и флаг инициализируется равным 0 (перед многопоточной частью), и любой поток установит значение равным 1 или 0 (все они всегда равны одному значению), я делаюнужна директива "#pragma omp atomic"?

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

//DataStruct is self defined data structure
function (DataStruct *data) {
  int i,flag=0;

  #pragma omp parallel for
  for(i=0;i<data->maxval;i++) {
    //Do stuff
    if (/*check condition*/) {
      //data->printMesage is 0 or 1, and doesn't change. It is fixed
      //before calling this function
      //data->printMesage is also an int variable
      flag=data->printMesage;
    }
  }
  //End of for loop. The code is running in
  //single thread from here
  if (flag) {
    //Print message
  }
}

Это необходимо перед "flag = data-> printMesage;"добавить директиву #pragma omp atomic?

Ответы [ 2 ]

2 голосов
/ 27 апреля 2019

Учитывая, что вам нужен только общий результат после параллельной области, вы можете использовать reduction вместо atomic.

#pragma omp parallel for reduction(max:flag)
for(i=0; i<data->maxval; i++) {

Оба решения отлично подходятхоть.Только если вы установите flag, возможно, очень часто, сокращение принесет выигрыш в производительности.

2 голосов
/ 27 апреля 2019

Даже если сохраненное значение меньше размера слова, необходимо избегать состояния гонки двух потоков, читающих и записывающих одну и ту же ячейку памяти.Вам понадобится пара #pragma omp atomic write и #pragma omp atomic read, чтобы избежать условия гонки.Поскольку вы не можете защитить if(flag) {...} с помощью конструкции atomic, вам нужно будет ввести временную переменную для чтения флага в:

#pragma omp atomic read
tmp = flag
if (tmp) { ... }

Кроме того, вам может потребоваться сделать просмотр памяти дляпотоки согласуются либо с помощью конструкции flush, либо путем добавления seq_cst (последовательная согласованность памяти) или пары предложений acquire и release к конструкции atomic.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...