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

时间:2019-06-03 09:14:52

标签: c openmp cancellation

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

我已经尝试过#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 个答案:

答案 0 :(得分:1)

不。无法取消有序循环。

  

被取消的循环结构不能具有有序子句。

(参见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构造是否符合标准。