OpenMP 子句共享与关键

OpenMP clause shared vs critical

我有一个在多个线程上执行的循环。每个循环都会将一个值存储到一个全局向量中。向量索引变量由所有线程使用,每个线程在向量更新后递增索引。 必须保护对索引的访问。 OpenMP 中是如何进行保护的?

1/ 如果我指定#pragma omp parallel shared(k) 这会保护(同步访问)跨线程的 k-index 访问吗?

   int k = 0;
   #pragma omp parallel shared(k)
   for (int i = 1; i < d; ++i)
   {
      for (int j = 0; j < i; ++j)
      {
         my_vec[k++] = some_value; //no need to protect my_vector, if k is unique across trheads
      }
   }

2/是否需要使用临界区

   int k = 0;
   #pragma omp parallel
   for (int i = 1; i < d; ++i)
   {
      for (int j = 0; j < i; ++j)
      {
        #pragma omp critical (section_name)
        {
           my_vec[k++] = some_value;
        }
      }
   }

3/我是否需要同时使用共享子句和临界区块?

1/ If I specify #pragma omp parallel shared(k) Will this protect (synchronize access to) k-index access across threads?

如果您使用共享 k,您将有两个 竞争条件:

  1. 在更新变量k期间,即在操作k++.
  2. 访问数组期间my_vec操作期间my_vec[k++] = some_value;

具有相同 k 索引的多个线程可以互相重写 my_vec[k] 的值。

AFAIK 没有条件可以让变量共享来避免 race-condition。通常情况恰恰相反。如果您共享一个变量,您可能需要确保它不受并发线程更新的影响。

2/ Do I need to use critical section

如果您只使用临界区并且变量 k 在线程中是私有的,您将在访问数组 [=13] 期间遇到 race-condition =](在操作期间my_vec[k++] = some_value;)。尽管如此,如果没有另外指定(例如, private(k)),默认情况下 OpenMP 假定变量 k 在线程之间共享。因此,使用临界区足以确保mutual exclusion访问两个共享变量(变量k和数组my_vec)

3/do I need to use both, the shared clause and critical section block?

您可以明确指出变量 k 是共享的,但默认情况下选项 2) 就足够了。