gpt4 book ai didi

parallel-processing - 使用 openmp 优化 N-queen

转载 作者:行者123 更新时间:2023-12-01 06:32:12 25 4
gpt4 key购买 nike

我正在学习 OPENMP 并编写了以下代码来解决 nqueens 问题。

//Full Code: https://github.com/Shafaet/Codes/blob/master/OPENMP/Parallel%20N-  Queen%20problem.cpp
int n;

int call(int col,int rowmask,int dia1,int dia2)
{
if(col==n)
{
return 1;

}
int row,ans=0;
for(row=0;row<n;row++)
{
if(!(rowmask & (1<<row)) & !(dia1 & (1<<(row+col))) & !(dia2 & (1<<((row+n-1)-col))))
{
ans+=call(col+1,rowmask|1<<row,dia1|(1<<(row+col)), dia2|(1<<((row+n-1)-col)));
}
}
return ans;

}

double parallel()
{
double st=omp_get_wtime();
int ans=0;
int i;
int rowmask=0,dia1=0,dia2=0;
#pragma omp parallel for reduction(+:ans) shared(i,rowmask)
for(i=0;i<n;i++)
{
rowmask=0;
dia1=0,dia2=0;
int col=0,row=i;
ans+=call(1,rowmask|1<<row,dia1|(1<<(row+col)), dia2|(1<<((row+n-1)-col)));
}
printf("Found %d configuration for n=%d\n",ans,n);
double en=omp_get_wtime();
printf("Time taken using openmp %lf\n",en-st);
return en-st;

}
double serial()
{

double st=omp_get_wtime();
int ans=0;
int i;
int rowmask=0,dia1=0,dia2=0;
for(i=0;i<n;i++)
{
rowmask=0;
dia1=0,dia2=0;
int col=0,row=i;
ans+=call(1,rowmask|1<<row,dia1|(1<<(row+col)), dia2|(1<<((row+n-1)-col)));
}
printf("Found %d configuration for n=%d\n",ans,n);
double en=omp_get_wtime();
printf("Time taken without openmp %lf\n",en-st);
return en-st;

}
int main()
{
double average=0;
int count=0;
for(int i=2;i<=13;i++)
{
count++;
n=i;

double stime=serial();
double ptime=parallel();
printf("OpenMP is %lf times faster for n=%d\n",stime/ptime,n);
average+=stime/ptime;
puts("===============");
}
printf("On average OpenMP is %lf times faster\n",average/count);
return 0;

}

并行代码已经比普通代码快,但我想知道如何使用 openmp pragma 对其进行更多优化。我想知道我应该做什么才能获得更好的性能以及我不应该做什么。

提前致谢。

(请不要建议任何与并行编程无关的优化)

最佳答案

您的代码似乎使用了经典的回溯 N-Queens 递归算法,这对于 N-Queens 求解来说不是最快的,但是(由于简单)在并行基础实践方面是最生动的。
话虽如此:这非常简单,因此除了基本的“并行”和缩减之外,您不会期望它自然地展示许多高级 OpenMP 方法。

但是,就您正在寻找的学习并行性而言,并且可能是为了更清晰和更好的学习曲线,还有一个(在许多可能的)实现中可用,它使用相同的算法,但从教育中往往更具可读性和生动性看法:

void setQueen(int queens[], int row, int col) {
//check all previously placed rows for attacks
for(int i=0; i<row; i++) {
// vertical attacks
if (queens[i]==col) {
return;
}

// diagonal attacks
if (abs(queens[i]-col) == (row-i) ) {
return;
}
}

// column is ok, set the queen
queens[row]=col;
if(row==size-1) {
#pragma omp atomic
nrOfSolutions++; //Placed final queen, found a solution
}
else {
// try to fill next row
for(int i=0; i<size; i++) {
setQueen(queens, row+1, i);
}
}
}

//Function to find all solutions for nQueens problem on size x size chessboard.
void solve() {
#pragma omp parallel for
for(int i=0; i<size; i++) {
// try all positions in first row
int * queens = new int[size]; //array representing queens placed on a chess board. Index is row position, value is column.
setQueen(queens, 0, i);
delete[](queens);
}
}

此给定代码是 Intel Advisor XE 之一示例(适用于 C++ 和 Fortran);给定样本的并行化方面在给定 Parallel Programming Book 的第 10 章中以非常详细的方式进行了讨论。 (实际上,给定的章节只是使用 N-Queens 来演示如何使用工具来并行化一般的串行代码)。

Given Advisor n-queens sample 使用与您的算法基本相同的算法,但它用简单的并行 for + atomic 组合代替了显式归约。预计此代码效率较低,但更“程序式”和“教育性”更强,因为它展示了“隐藏的”数据竞争。如果您上传给定的示例代码,您实际上会发现使用 TBB、Cilk Plus 和 OpenMP(OMP 用于 C++ 和 Fortran)的 4 个等效的 N-Queens 并行实现。

关于parallel-processing - 使用 openmp 优化 N-queen,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19078635/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com