C 递归任务创建导致OpenMP中出现分段错误
我正在尝试用OpenMP实现一个nqueens解算器,我的串行代码工作得很好,但是当我尝试在上面执行任务并行时,我得到了分段错误或空行/列 以下是我的实现:C 递归任务创建导致OpenMP中出现分段错误,c,parallel-processing,openmp,multitasking,C,Parallel Processing,Openmp,Multitasking,我正在尝试用OpenMP实现一个nqueens解算器,我的串行代码工作得很好,但是当我尝试在上面执行任务并行时,我得到了分段错误或空行/列 以下是我的实现: #define N 8 bool SOLUTION_EXISTS = false; // THIS IS GLOBAL bool solve_NQueens(int board[N][N], int col) { if (col == N) { #pragma omp critical
#define N 8
bool SOLUTION_EXISTS = false; // THIS IS GLOBAL
bool solve_NQueens(int board[N][N], int col)
{
if (col == N)
{
#pragma omp critical
print_solution(board);
SOLUTION_EXISTS = true;
return true;
}
for (int i = 0; i < N; i++)
{
if (can_be_placed(board, i, col) )
{
#pragma omp taskgroup
{
#pragma omp task private(col) shared(i) firstprivate(board)
{
board[i][col] = 1;
SOLUTION_EXISTS = solve_NQueens(board, col + 1) || SOLUTION_EXISTS;
board[i][col] = 0;
}
}
}
}
return SOLUTION_EXISTS;
}
当我将col设置为private时,它给出了一个分段错误。如果我没有设置任何变量范围,就会打印出不明确和错误的解决方案
我使用的是gcc4.8.5
解决方案
由于使用了private(col)
,因此存在分段错误。因此,col
不会从函数中复制,甚至不会初始化。使用firstprivate(col)
制作col
的正确副本
劝告
omp任务组
将使您的代码按顺序运行,因为在作用域的末尾有一个隐含的障碍。最好避免它(例如,在循环结束时使用omp taskwait
,并稍微更改其余代码)。
如果您想更改,请注意必须使用firstprivate
而不是shared
复制i
此外,避免在并行代码中使用全局变量,如
SOLUTION\u。这通常会导致很多问题,从恶意bug到代码速度变慢。如果您仍然需要/想要这样做,则必须使用例如omp-atomic
或omp-critical
指令来保护多线程中使用的变量。全局变量通常会导致问题,尤其是递归函数和/或线程/并行性。结合两者-哎哟!我不知道OMP,所以也许我根本不应该发表评论,但在我看来,共享状态太多,你会遇到各种各样的问题。嘿,谢谢你的建议,但我尝试了你的说法,但没有效果。现在,它返回的结果是,所有执行中都不存在解决方案。嘿,伙计,帮帮我,我的性能大幅下降。当然,我预计会有所放缓,但不会慢10倍。
#pragma omp parallel
{
#pragma omp single
{
solve_NQueens(board, 0);
}
}