如何打破OpenMP循环?

6

我有一个非常占用 CPU 的循环过程 (5000 万次以上的调用和超过 1000 亿次的循环阶段),例如:

for(int i=0;i<*string;i++){
    if(!check_some_stuff(string+i)) {
        do_some_stuff(i,string-2);
        if(!string)
            break;
       do_yet_other_stuff(string);
    }
}

由于在#pragma omp parallel for ordered中不允许使用break语句,所以我想将i设置为非常大的值。

for(int i=0;i<*string;i++){
    if(!check_some_stuff(string+i)) {
        do_some_stuff(i,string-2);
        if(!string)
            i=0x7FFFFFFB;
       do_yet_other_stuff(string);
    }
}

这个功能可以在没有 OpenMP 的情况下完美运行。但是,当我添加

#pragma omp parallel for ordered shared(string)
for(int i=0;i<*string;i++){
    if(!check_some_stuff(string+i)) {
        do_some_stuff(i,string-2);
        #pragma omp critical
        if(!string)
            i=0x7FFFFFFB; // it seems the assignment has no effect on the value of i.
       do_yet_other_stuff(*string);
    }
}

i的值似乎没有改变,所以它进入了一个无限循环。


1
在并行版本中,更改“i”将具有不可预测的结果,因为假定循环的每次迭代都由单独的线程处理。更改一个线程中的值很可能不会影响其他线程。 - Mad Physicist
1
@MadPhysicist:我找不到如何使用OpenMP完成这个问题的相关信息。这就是那个问题的主题。它绝对需要一个详细的答案才能理解如何操作。 - user2284570
@MadPhysicist:这是gcc 5.2.0(openmp标准的最新版本)附带的版本。使用#pragma,i=0x7FFFFFFB;成为一个本地更改,不影响外部循环。你说的是关键的那个吗?我加上它是因为我认为需要防止其他线程在i=0x7FFFFFFB;之后修改字符串,所以可以安全地将其删除。 - user2284570
@user2284570 你是指像这个这样的东西吗? - Michi
#pragma omp cancel - Ilya Verbin
显示剩余8条评论
1个回答

1
这有帮助吗?
int abort = 0;
#pragma omp parallel for ordered shared(string, abort)
for(int i=0;i<*string;i++)
{
    #pragma omp flush(abort)
    if(!abort)
    {
        if(!check_some_stuff(string+i))
        {
            #pragma omp flush(abort)
            if(!abort) do_some_stuff(i,string-2);
            if(!string) abort = 1;
            #pragma omp flush(abort)
            if(!abort) do_yet_other_stuff(*string);
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接