关键部分openMP

时间:2014-03-14 21:23:08

标签: c++ multithreading critical-section openmp

我想知道我们需要在哪里设置关键部分?

如果有多个线程具有共享阵列,并且每个线程都需要 在不同的地方写作是否需要处于关键部分,即使每个部分也是如此 线程写入数组中的其他位置?

让我说我有2维数组M [3] [3],initial_array [3]和一些双变量 我想计算一些东西并将其存储在M的第一列。 我可以使用for循环,但我想使用openMP,所以我做了:

 omp_set_num_threads(3);
 #pragma omp parallel shared(M,variable)
 {  
     int id = omp_get_thread_num();
     double init = initial_array[id]*variable;
     M[id][0] = init;
 }   

它工作正常,但我知道它可能导致死锁或运行时间不佳。 我的意思是如果我有更多的线程,甚至更大的M .. 设置关键部分的正确方法是什么? 我想问的另一件事是关于initial_array,是否还需要共享?

2 个答案:

答案 0 :(得分:2)

这是安全的代码。

数组中的随机访问不会对数组中的其他元素造成任何竞争条件。只要您继续同时读取和写入数组中的非共享元素,您就不会遇到竞争条件。

请记住,读取可以使用写入进行竞争,具体取决于元素的类型和大小。您的示例显示double,如果您在相同元素上同时执行写入操作,我会担心。在写入期间可能存在上下文切换,但这取决于您的arch / platform。无论如何,你不是这样做的,但值得一提。

答案 1 :(得分:2)

我没有看到任何关于并发性的问题,因为你正在访问内存的不同部分(数组的不同索引),但我看到的唯一问题是如果你的内核具有专用的L1缓存,则会遇到性能问题。

在这种情况下,由于缓存一致性会导致性能下降,其中一个更新索引,使其他人无效,执行回写等。对于少量线程/核心不是问题但是在大量运行的线程上核心它确定它。 因为运行的线程数据不是真正独立的,所以它们被读取为缓存中的数据块(如果您正在访问M [0] [0],那么不仅M [0] [0]被读入高速缓存但M [0] [0]到M [n] [col],其中n取决于高速缓存块大小)。如果块很大,它可能包含更多的共享数据。