Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 临界截面openMP_C++_Multithreading_Critical Section_Openmp - Fatal编程技术网

C++ 临界截面openMP

C++ 临界截面openMP,c++,multithreading,critical-section,openmp,C++,Multithreading,Critical Section,Openmp,我想知道我们需要在哪里设置关键部分 如果有多个线程具有共享数组,并且每个线程都需要 要在不同的地方写作,是否需要在关键部分,即使每个部分都是如此 线程写入到数组中的其他位置 假设我有二维数组M[3][3],初始数组[3]和一些双变量 我想计算一些东西,然后把它存储在M的第一列。 我可以与for循环一起使用,但我想与openMP一起使用,所以我做到了: omp_set_num_threads(3); #pragma omp parallel shared(M,variable) {

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

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

假设我有二维数组M[3][3],初始数组[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。。 设置临界截面的正确方法是什么? 我想问的另一件事是关于初始_数组,它是否也需要共享

这是安全代码

数组中的随机访问不会对数组中的其他元素造成任何竞争条件。只要您继续并发地读写阵列中的非共享元素,就永远不会遇到竞争条件

请记住,根据元素的类型和大小,读操作可能与写操作竞争。您的示例显示了
double
,我关心的是,您是否在同一元素上同时执行了读操作和写操作。写操作期间可能会有上下文切换,但这取决于您的arch/平台。无论如何,您没有这样做,但值得一提。

这是安全的代码

数组中的随机访问不会对数组中的其他元素造成任何竞争条件。只要您继续并发地读写阵列中的非共享元素,就永远不会遇到竞争条件


请记住,根据元素的类型和大小,读操作可能与写操作竞争。您的示例显示了
double
,我关心的是,您是否在同一元素上同时执行了读操作和写操作。写操作期间可能会有上下文切换,但这取决于您的arch/平台。无论如何,您没有这样做,但值得一提。

我看不出并发性有任何问题,因为您正在访问内存的不同部分(阵列的不同索引),但我看到的唯一问题是,如果您的内核有专用的L1缓存,那么性能会受到影响


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

我认为并发性没有任何问题,因为您正在访问内存的不同部分(阵列的不同索引),但我看到的唯一问题是,如果您的内核具有专用的L1缓存,那么性能会受到影响


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

谢谢你的回答,实际上我正在实现维特比算法,所以原始代码中的双变量来自发射矩阵。作为“emission[id][col]”(col在并行部分之前计算,并在线程之间共享),我上面给出的代码是viterbi算法的初始化。感谢您的回答,实际上我正在实现viterbi算法,因此原始代码中的双变量来自emission矩阵。作为“emission[id][col]”(col在并行部分之前计算,并在线程之间共享),我上面给出的代码是viterbi算法的初始化。感谢您的回答,实际上我正在实现viterbi算法,因此原始代码中的双变量来自emission矩阵。作为“emission[id][col]”(col在并行部分之前计算,并在线程之间共享),这是viterbi算法的init感谢答案,实际上我正在实现viterbi算法,因此原始代码中的双变量来自emission矩阵。作为“emission[id][col]”(col在并行部分之前计算,并在线程之间共享),这是viterbi算法的init