递归任务创建导致OpenMP中的分段错误

问题描述 投票:-1回答:1

[我正在尝试使用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
            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; 
}

此函数的第一个调用是:

#pragma omp parallel
{
    #pragma omp single
    {
        solve_NQueens(board, 0);
    }
}

[当我将col设为私有时,会出现分段错误。如果我不放置任何可变范围,则会打印出模棱两可和错误的解决方案。

而且我正在使用gcc 4.8.5

c parallel-processing openmp multitasking
1个回答
0
投票

解决方案

因为使用private(col),所以存在分段错误。因此,col不会从您的函数中复制,甚至不会初始化。使用firstprivate(col)正确复制col

建议

omp taskgroup将使您的代码按顺序运行,因为作用域末尾存在隐式障碍。最好避免这种情况(例如,在循环结束时使用omp taskwait并在其余代码中稍加更改)。如果要更改此设置,请注意,必须使用i而不是firstprivate复制shared

此外,请避免在并行代码中使用诸如SOLUTION_EXISTS之类的全局变量。通常,这会导致从恶性错误到速度慢的代码的问题。并且,如果您仍然需要/想要这样做,则必须使用例如omp atomicomp critical指令对多线程中使用的变量进行保护

© www.soinside.com 2019 - 2024. All rights reserved.