C++ 临界截面openMP
我想知道我们需要在哪里设置关键部分 如果有多个线程具有共享数组,并且每个线程都需要 要在不同的地方写作,是否需要在关键部分,即使每个部分都是如此 线程写入到数组中的其他位置 假设我有二维数组M[3][3],初始数组[3]和一些双变量 我想计算一些东西,然后把它存储在M的第一列。 我可以与for循环一起使用,但我想与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) {
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