有没有办法从有序条款中取消?

Is there a way to cancel from inside ordered clause?

我正在开发一个程序,使用多线程计算一定数量的素数。现在我 运行 遇到了在所述素数后退出线程的问题。

我试过 #pragma omp cancel for,但我不能在有序子句中使用它。还有其他方法可以 "break" 循环吗?

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
      }
    }
  }
}

我想在找到所需数量的素数后立即"break"循环,如果我没记错的话,必须在有序子句中完成。

没有。无法取消有序循环。

A loop construct that is canceled must not have an ordered clause.

(参见 OpenMP 标准的 2.14.1)

模拟取消的解决方法之一是在循环的开头添加一个跳过,例如

#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++;

P.S。我不是 100% 确定它是否符合条件 ordered 构造的标准。