C 如何解决;返回0或返回1“;在open mp中的for循环中?

C 如何解决;返回0或返回1“;在open mp中的for循环中?,c,openmp,C,Openmp,这就是我到目前为止为解决返回1所做的工作,返回0,它实际上是一个使用回溯算法的数独解算器,所以我尝试将其并行化,但我无法得到完整的结果。(如果我的实现错误,请更正我) 到底发生了什么? 谁能帮忙 这就是我所指的网站,我过去一直遵循他们的方式: //返回1是原始的串行代码,因为的并行中不允许使用返回,所以我使用了#pragma opm flush来消除它,但结果并不完整,它在数独中仍然留下了一些空白网格 感谢您的回答:>首先,由于解算器是递归调用的,因此它会在每个递归级别上使线程数加倍。我认为这不

这就是我到目前为止为解决
返回1所做的工作
返回0,它实际上是一个使用回溯算法的数独解算器,所以我尝试将其并行化,但我无法得到完整的结果。(如果我的实现错误,请更正我)
到底发生了什么?
谁能帮忙

这就是我所指的网站,我过去一直遵循他们的方式:

//返回1
是原始的串行代码,因为
的并行中不允许使用返回,所以我使用了#pragma opm flush来消除它,但结果并不完整,它在数独中仍然留下了一些空白网格


感谢您的回答:>

首先,由于
解算器
是递归调用的,因此它会在每个递归级别上使线程数加倍。我认为这不是你想做的。 编辑:只有使用
omp\u set\u nested()
启用了嵌套并行性,并且默认情况下不是这样,这才是正确的。因此,只有第一次调用
solver
时才会分叉

#pragma omp parallel num_threads(2)
#pragma omp parallel for
在您的代码中,尝试在另一个并行区域中创建一个并行区域,这将导致后面的循环执行两次,因为外部
parallel
已经创建了两个线程。这应该被替换为

#pragma omp parallel num_threads(2)
#pragma omp for
或用于num_线程(2)的等效的
#pragma omp parallel

第二,此代码:

if (checkExist(row,col,i))//if not, assign number i to the empty cell
    outBoard[row][col] = i; 
创建竞争条件,两个线程并行地将不同的值写入同一单元格。您可能希望为每个线程创建一个单独的电路板副本

另一个代码部分

if (outBoard[row][col] != inBoardA[row][col]) 
    outBoard[row][col] = 0;
似乎在并行区域之外,但在对
解算器的嵌套调用中,它也在最外层的
解算器创建的不同线程中并行执行

Final(e)(18.09)无论如何,即使您设法调试/更改代码以使其正确并行运行(正如我自己所做的那样,只是为了检查一下-如果有人感兴趣,我会尝试提供代码,我对此表示怀疑),结果将是并行执行此代码不会给您带来太多好处。我想到的原因如下:

想象一下,当
solver
迭代9个可能的单元格值时,它会创建9个执行分支。如果使用OpenMP创建2个线程,它将以某种方式在线程之间分配顶级分支,例如一个线程执行5个分支,另一个线程执行4个分支,并且在每个线程中,分支将逐个连续执行。若初始数独状态有效,则只有一个分支将导致正确的解决方案。当其他分支在解决方案中遇到差异时,它们将被截断,因此一些分支运行时间更长,一些分支运行时间更短,而导致正确解决方案的分支运行时间最长。您无法预测执行哪些分支需要多长时间,因此无法合理地平衡线程之间的工作负载。即使使用OpenMP动态调度,也有可能在一个线程执行最长的分支时,其他线程已经完成所有其他分支并等待最后一个分支,因为分支太少(因此动态调度没有什么帮助)

由于在线程之间创建线程和同步数据会产生一些巨大的开销(与0.01-10 ms的顺序
解算器运行时间相比),因此您会看到并行执行时间比顺序执行时间稍长或短,具体取决于输入


在任何情况下,如果顺序解算器的运行时间低于10毫秒,为什么要使其并行?

“我希望我的代码不会把你搞砸”不,不会,但你的拼写和语法很糟糕。请至少试着把它整理一下,让它可读。@Tony,原谅我的英语不好,我会提高它。如果你能回答我的问题,我很高兴?我没有openmp的任何经验,所以不能帮助你。对不起的:(你在文章中提到的循环分支方式是一个糟糕的想法。OpenMP不是为此而设计的。OpenMP是一种数据并行范例,应该只用于简单的数据并行算法。对于任何更复杂的问题,都可以使用其他范例。@Hristo,我将#pragma omp parallel改为#pragma omp parallel,它可以得到正确的结果…我想知道为什么现在…递归线程加倍只有在他显式启用嵌套并行时才会发生,因为它在默认情况下是禁用的。是的,函数没有完成,if(标志)后面还有几行函数我猜,如果没有找到解决方案,您会清除单元格,从而造成更多混乱。因此,一个线程可能会清除单元格,而另一个线程仍然认为它可以与自己版本的电路板一起工作。此外,您是否尝试过使用num_线程测试此版本(1)?设置flag=TRUE后,您不会立即退出循环,而是继续执行
if(checkExist(row,col,i))outbound[row][col]=i;
@VictorKuznetsov,是的,它与num_线程(1)一起工作,我还消除了#pragma omp parallel,因为正如Histro所说,持续时间是num_线程(2)的两倍…这意味着我的程序现在可以了!?我现在对我的编码技术感到很难过。
if (checkExist(row,col,i))//if not, assign number i to the empty cell
    outBoard[row][col] = i; 
if (outBoard[row][col] != inBoardA[row][col]) 
    outBoard[row][col] = 0;