【问题标题】:Is there a way to cancel from inside ordered clause?有没有办法从有序条款中取消?
【发布时间】:2019-10-18 19:51:52
【问题描述】:

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

我试过#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
      }
    }
  }
}

当我找到所需数量的素数时,我想立即“打破”循环,如果我没记错的话,必须在有序子句内完成。

【问题讨论】:

  • for 循环中可以有两个条件。 candidate &lt;= end &amp;&amp; prime_counter &lt; max_primes;
  • @WeatherVane 不,这不是omp for 的有效循环形式。

标签: c openmp cancellation


【解决方案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++;

附:我不是 100% 确定有条件的 ordered 构造是否符合标准。

【讨论】:

  • 您能解释一下线程安全的含义吗?使用线程安全方法的结果会有什么不同吗?
  • 如果访问prime_counter时不添加atomic子句,则结果未定义。很可能它会起作用。由于本地副本未更新,您可能会执行大量额外工作。不太可能,但有可能,循环永远不会停止或过早停止。
猜你喜欢
  • 2012-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-03
  • 1970-01-01
  • 2014-10-07
  • 2012-07-11
  • 1970-01-01
相关资源
最近更新 更多