我遇到了一个非常奇怪的OpenMP问题,我无法弄明白。这就是它的样子。
我(让我们说)有四个功能
function0(Data *data) { ..body.. }
function1(Data *data) { ..body.. }
function2(Data *data) { ..body.. }
function3(Data *data) { ..body.. }
这些功能可能会也可能不会修改data
以下是按顺序调用它们的方式
// Version 1
void test(Data *data)
{
function0(data);
function1(data);
function2(data);
function3(data);
}
我可以随心所欲地重新安排电话,但它仍然可以完美无缺。所以我假设他们不知何故(?)独立。
现在并行化时
// Version 2
void test(Data *data)
{
int th_id;
#pragma omp parallel private(th_id) default(shared)
{
th_id = omp_get_thread_num();
if(th_id==0) {
function0(data);
}
if(th_id==1) {
function1(data);
}
if(th_id==2){
function2(data);
}
if(th_id==3){
function3(data);
}
}
}
它不起作用(版本2)。
但是如果我在每次调用后同步线程就可以了
// Version 3
void test(Data *data)
{
int th_id;
#pragma omp parallel private(th_id) default(shared)
{
th_id = omp_get_thread_num();
if(th_id==0) {
function0(data);
}
#pragma omp barrier
if(th_id==1) {
function1(data);
}
#pragma omp barrier
if(th_id==2){
function2(data);
}
#pragma omp barrier
if(th_id==3){
function3(data);
}
}
}
我在想data
但是当我重新安排呼叫时,为什么它会工作(在顺序版本1中)?
答案 0 :(得分:2)
假设您有两个这样的功能
function0(int *data)
{
*data = *data + 1;
}
function1(int *data)
{
*data = *data + 2;
}
显然,您可以按顺序以任意顺序运行这两个操作,最后该值将增加3。 但是,如果你并行运行这两个函数,那么你就会有一个数据竞争,并且它的一个添加内容将会丢失,所以你可以得到任何初始值增加1,2或3。
仅仅因为这些函数似乎是可交换的顺序,并不意味着它们可以安全地并行运行。