Есть ли способ отменить заказ изнутри? - PullRequest
0 голосов
/ 03 июня 2019

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

Я пробовал #pragma omp cancel for, но не могу использовать его внутри упорядоченного предложения. Есть ли другой способ «разорвать» петлю?

void get_primes(prime_type start, prime_type end) {
  #pragma omp parallel for ordered schedule(dynamic) shared(prime_counter)
  for (candidate = start; candidate <= end; candidate += 2) {
    if (is_prime(candidate)) {
      #pragma omp ordered
      {
        primes[prime_counter] = candidate;
        prime_counter++;
        if (prime_counter >= max_primes) {
          #pragma omp cancel for
        }
        #pragma omp cancellation point for
      }
    }
  }
}

Я хочу немедленно "разорвать" цикл, когда я нашел желаемое количество простых чисел, и если я не ошибаюсь, это должно быть сделано в упорядоченном предложении.

1 Ответ

1 голос
/ 03 июня 2019

Нет.Невозможно отменить упорядоченный цикл.

Отменяемая конструкция цикла не должна иметь упорядоченного предложения.

(см. 2.14.1 OpenMPстандарт)

Одним из способов эмуляции отмены является добавление пропуска в начале цикла, например,

#pragma omp parallel for ordered schedule(dynamic) shared(prime_counter)
for (candidate = start; candidate <= end; candidate += 2) {
  if (prime_counter >= max_primes) {
    continue;
  }
  if (is_prime(candidate)) {

Однако это еще не потокобезопасный доступ к prime_counter.Чтобы избежать условий гонки, вы должны сделать что-то вроде:

  int local_prime_counter;
  #pragma omp atomic read
  local_prime_counter = prime_counter;
  if (local_prime_counter >= max_primes)

  ...

  #pragma omp atomic update
  prime_counter++;

PS. Я не совсем уверен на 100%, соответствует ли стандарт условной конструкции ordered.

...