OpenMP 子句共享与关键
Posted
技术标签:
【中文标题】OpenMP 子句共享与关键【英文标题】:OpenMP clause shared vs critical 【发布时间】: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/我需要同时使用共享子句和临界区块吗?
【问题讨论】:
【参考方案1】:1/ 如果我指定 #pragma omp parallel shared(k) 这会保护 (同步访问)跨线程的 k-index 访问?
如果您使用共享的k
,您将有两个竞争条件:
-
在变量
k
更新期间,即在操作k++
中。
在访问数组期间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) 就足够了。
【讨论】:
以上是关于OpenMP 子句共享与关键的主要内容,如果未能解决你的问题,请参考以下文章