【问题标题】:OpenMP clause shared vs criticalOpenMP 子句共享与关键
【发布时间】:2021-08-13 01:40:27
【问题描述】:

我在多个线程上执行了一个循环。每个循环都会将一个值存储到一个全局向量中。所有线程都使用向量索引变量,每个线程在向量更新后递增索引。 必须保护对索引的访问。 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/我需要同时使用共享子句和临界区块吗?

【问题讨论】:

    标签: c++ multithreading performance parallel-processing openmp


    【解决方案1】:

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

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

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

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

    AFAIK 没有条件使变量共享可以避免 race-condition。通常情况正好相反。如果你让一个变量共享,你可能需要确保它受到保护以防止并发线程更新。

    2/ 我需要使用临界区吗

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

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

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

    【讨论】:

      猜你喜欢
      • 2012-07-05
      • 2018-01-30
      • 1970-01-01
      • 2013-06-05
      • 2011-08-22
      • 1970-01-01
      • 2014-03-02
      • 1970-01-01
      • 2012-11-18
      相关资源
      最近更新 更多