并行计算八皇后问题讲解.docx
《并行计算八皇后问题讲解.docx》由会员分享,可在线阅读,更多相关《并行计算八皇后问题讲解.docx(49页珍藏版)》请在冰豆网上搜索。
![并行计算八皇后问题讲解.docx](https://file1.bdocx.com/fileroot1/2023-6/10/ef3cba2d-ff51-45dd-9592-82fe4d64baff/ef3cba2d-ff51-45dd-9592-82fe4d64baff1.gif)
并行计算八皇后问题讲解
并行计算与多核多线程技术
课程报告
班级__________________
学号_____________
姓名_________________
2014年11月26日
1.N皇后问题并行算法设计与实现1
1.1功能描述与解决方案1
1.1.1功能描述1
1.1.2解决方案1
1.2算法设计1
1.2.1串行算法设计1
1.2.2并行算法设计2
1.2.3理论加速比分析(选作)3
1.3基于OpenMP的并行算法实现3
1.3.1代码及注释(变量名名字首字母开头)3
1.3.2执行结果截图(体现串行时间、并行时间和加速比)7
1.3.3遇到的问题及解决方案8
1.4基于MPI的并行算法实现9
1.4.1代码及注释(变量名名字首字母开头)9
1.4.2执行结果截图(体现串行时间、并行时间和加速比)13
1.4.3遇到的问题及解决方案14
1.5基于Java(Tread或者Runnable)的并行算法实现15
1.5.1代码及注释(变量名名字首字母开头)15
1.5.2执行结果截图(体现串行时间、并行时间和加速比)19
1.5.3遇到的问题及解决方案21
1.6基于Windows(API或MFC或.net)的并行算法实现21
1.6.1代码及注释(变量名名字首字母开头)21
1.6.2执行结果截图(体现串行时间、并行时间和加速比)26
1.6.3遇到的问题及解决方案27
1.7基于Linux(fork或pthread)的并行算法实现28
1.7.1代码及注释(变量名名字首字母开头)28
1.7.2执行结果截图(体现串行时间、并行时间和加速比)32
1.7.3遇到的问题及解决方案33
2.理论基础34
2.1并行计算机体系结构、并行计算模型、并行算法的概念34
2.2并行计算机体系结构、并行计算模型、并行算法的关系34
2.3实例说明并行计算机体系结构、并行计算模型、并行算法的关系34
评价
实践效果(正确度/加速比)
理论基础
难度
工作量
独立性
1.N皇后问题并行算法设计与实现
1.1功能描述与解决方案
1.1.1功能描述
八皇后问题是十九世纪著名数学家高斯于1850年提出的。
问题是:
在8*8的棋盘上摆放8个皇后,使其不能互相攻击,即任意的两个皇后不能处在同意行,同一列,或同意斜线上。
可以把八皇后问题拓展为n皇后问题,即在n*n的棋盘上摆放n个皇后,使其任意两个皇后都不能处于同一行、同一列或同一斜线上。
1.1.2解决方案
1、此题有多重解法,常见解法有残卷法(即穷举法,但时间复杂度和空间复杂度均为N^N,并不高效)和递归+回溯算法(本次采用此算法)。
2、判断当前放置的皇后“安全”的依据为同行、同列、对角线-\、对角线-/的遍历结果均为TRUE即没有不满足问题条件的皇后存在。
3、第一个线程从第一列第一行的坐标开始放置皇后,其他线程从其他列第一行的元素开始递归放置皇后,每放置一个皇后,判断其是否安全,若“安全”则继续在当前列和(当前行+1)处放置下一个皇后,若不安全则将当前皇后坐标设为0。
4、采用三维数组m[THREAD][QUEENS][QUEENS]来存放棋盘的放置状态,第一维用于保证各线程不会影响其他线程的放置状态,第二、三维用来确定棋盘的规格。
1.2算法设计
1.2.1串行算法设计
/**
*wy_serial_listAllCol:
ListAllTheValidChessTableInSerialWay
*
*@paramm[][][]
*@paramy
*/
staticvoidwy_serial_listAllCol(intm[THREADS][QUEENS][QUEENS],inty){for(intx=0;xm[0][x][y]=1;
if(wy_isOk(m,x,y,0)){
if(y==QUEENS-1){
//print(m,0);
}else
wy_serial_listAllCol(m,y+1);
}
m[0][x][y]=0;
}
}
1.2.2并行算法设计
OpenMP使用parallelfor来调用listFirstCol()函数,listFirstCol再递归调用listSecondCol()函数来实现各线程并行递归回溯
其他语言使用并行区域的办法来保证各线程并行递归回溯
/**
*wy_parallel_listOtherCol:
DetermineTheOtherColsInParallelWay
*
*@paramm[][][]
*@paramy
*@paramthread
*/
staticvoidwy_parallel_listOtherCol(intm[THREADS][QUEENS][QUEENS],inty,intthread){
for(intx=0;xm[thread][x][y]=1;
if(wy_isOk(m,x,y,thread)){
if(y==QUEENS-1){
//print(m,omp_get_thread_num());
}else
wy_parallel_listOtherCol(m,y+1,thread);
}
m[thread][x][y]=0;
}
}
/**
*wy_parallel_listFirstCol:
DetermineTheFirstColInParallelWay
*
*@paramm[][][]
*@paramy
*/
staticvoidwy_parallel_listFirstCol(intm[THREADS][QUEENS][QUEENS],inty){
#pragmaompparallelfor
for(intx=0;x//printf("thread_num%d\n",omp_get_thread_num());
m[omp_get_thread_num()][x][y]=1;
if(wy_isOk(m,x,y,omp_get_thread_num())){
wy_parallel_listOtherCol(m,y+1,omp_get_thread_num());
}
m[omp_get_thread_num()][x][y]=0;
}
}
1.2.3理论加速比分析(选作)
在N皇后问题中,加速比一般为Thread数目,最高加速比为N。
因为最多允许N个线程同时运行。
1.3基于OpenMP的并行算法实现
1.3.1代码及注释(变量名名字首字母开头)
//YTUWangYang123-2201258503222OpenMPN-QUEEN
#include"stdafx.h"
#defineQUEENS8/*QUEENSNUM*//*8QUEENSHAVA92RES*/
#defineTHREADS4/*THREADSTOTALNUM*/
/**
*wy_isOk:
CheckTheCurrentQueenSiteValidity
*
*@paramx
*@paramy
*@returnbool-value
*/
staticboolwy_isOk(intm[THREADS][QUEENS][QUEENS],intx,inty,intthread){
inttx,ty;
/*Samerow,returnfalse*/
for(ty=0;tyif(m[thread][x][ty]==1)returnfalse;
}
/*Samecol,impossible*/
/*Diagonal\,returnfalse*/
tx=x;ty=y;
while(--tx>=0&&--ty>=0){
if(m[thread][tx][ty]==1)returnfalse;
}
/*Diagonal/,returnfalse*/
tx=x;ty=y;
while(++tx=0){
if(m[thread][tx][ty]==1)returnfalse;
}
returntrue;
}
/**
*count:
CurrentCount
*/
staticintcount=1;
/**
*print:
PrintCurrentFinishedChessTable
*
*@paramm[][][]
*@paramthread
*/
staticvoidprint(intm[THREADS][QUEENS][QUEENS],intthread){
printf(">%d\n",count);
count++;
for(inti=0;ifor(intj=0;jprintf("%d",m[thread][i][j]);
}
printf("\n");
}
}
/**
*wy_serial_listAllCol:
ListAllTheValidChessTableInSerialWay
*
*@paramm[][][]
*@paramy
*/
staticvoidwy_serial_listAllCol(intm[THREADS][QUEENS][QUEENS],inty){
for(intx=0;xm[0][x][y]=1;
if(wy_isOk(m,x,y,0)){
if(y==QUEENS-1){
//print(m,0);
}else
wy_serial_listAllCol(m,y+1);
}
m[0][x][y]=0;
}
}
/**
*wy_parallel_listOtherCol:
DetermineTheOtherColsInParallelWay
*
*@paramm[][][]
*@paramy
*@paramthread
*/
staticvoidwy_parallel_listOtherCol(intm[THREADS][QUEENS][QUEENS],inty,intthread){
for(intx=0;xm[thread][x][y]=1;
if(wy_isOk(m,x,y,thread)){
if(y==QUEENS-1){
//print(m,omp_get_thread_num());
}else
wy_parallel_listOtherCol(m,y+1,thread);
}
m[thread][x][y]=0;
}
}
/**
*wy_parallel_listFirstCol:
DetermineTheFirstColInParallelWay
*
*@paramm[][][]
*@paramy
*/
staticvoidwy_parallel_listFirstCol(intm[THREADS][QUEENS][QUEENS],inty){
#pragmaompparallelfor
for(intx=0;x//printf("thread_num%d\n",omp_get_thread_num());
m[omp_get_thread_num()][x][y]=1;
if(wy_isOk(m,x,y,omp_get_thread_num())){
wy_parallel_listOtherCol(m,y+1,omp_get_thread_num());
}
m[omp_get_thread_num()][x][y]=0;
}
}
int_tmain(intargc,_TCHAR*argv[]){
intm[THREADS][QUEENS][QUEENS];
/*ParallelPart*/
omp_set_num_threads(THREADS);
clock_tt1=clock();
for(inti=0;ifor(intj=0;jfor(intz=0;zm[i][j][z]=0;
}
}
}
wy_parallel_listFirstCol(m,0);
clock_tt2=clock();
floatpt=t2-t1;
printf("NQUEEN:
N=%d\n",QUEENS);
printf("ParallelTime=%f\n",pt);
/*SerialPart*/
t1=clock();
for(inti=0;ifor(intj=0;jfor(intz=0;zm[i][j][z]=0;
}
}
}
wy_serial_listAllCol(m,0);
t2=clock();
floatst=t2-t1;
printf("SerialTime=%f\n",st);
printf("相对加速比=%f\n",st/pt);
getch();
return0;
}
1.3.2执行结果截图(体现串行时间、并行时间和加速比)
(1)小数据量验证正确性的执行结果
N=12SerialTime=498,ParallelTime=1235
相对加速比=2.479
(2)大数据量获得较好加速比的执行结果
N=14SerialTime=20340,ParallelTime=41072
相对加速比=2.019
1.3.3遇到的问题及解决方案
(1)问题一
错误代码及后果
当数组m维数为2维时,无法避免其他线程对当前线程的影响,各线程存在数据竞争,无法准确的描述棋盘放置状态。
正确代码
应将数组设置为3维,第1维为Thread维,避免多线程共同操作同一个棋盘,出现数据竞争。
分析
OpenMP和Intel的CPU兼容很好,所以加速比很理想。
1.4基于MPI的并行算法实现
1.4.1代码及注释(变量名名字首字母开头)
//YTUWangYang123-2201258503222MPIN-QUEEN
#include"stdafx.h"
#defineQUEENS8/*QUEENSNUM*//*8QUEENSHAVE92RES*/
#defineTHREADS2/*THREADSTOTALNUM*/
/**
*wy_isOk:
CheckTheCurrentQueenSiteValidity
*
*@paramx
*@paramy
*@returnbool-value
*/
staticboolwy_isOk(intm[THREADS][QUEENS][QUEENS],intx,inty,intthread){
inttx,ty;
/*Samerow,returnfalse*/
for(ty=0;tyif(m[thread][x][ty]==1)returnfalse;
}
/*Samecol,impossible*/
/*Diagonal\,returnfalse*/
tx=x;ty=y;
while(--tx>=0&&--ty>=0){
if(m[thread][tx][ty]==1)returnfalse;
}
/*Diagonal/,returnfalse*/
tx=x;ty=y;
while(++tx=0){
if(m[thread][tx][ty]==1)returnfalse;
}
returntrue;
}
/**
*count:
CurrentCount
*/
staticintcount=1;
/**
*print:
PrintCurrentFinishedChessTable
*
*@paramm[][][]
*@paramthread
*/
staticvoidprint(intm[THREADS][QUEENS][QUEENS],intthread){
printf(">%d\n",count);
count++;
for(inti=0;ifor(intj=0;jprintf("%d",m[thread][i][j]);
}
printf("\n");
}
}
/**
*wy_serial_listAllCol:
ListAllTheValidChessTableInSerialWay
*
*@paramm[][][]
*@paramy
*/
staticvoidwy_serial_listAllCol(intm[THREADS][QUEENS][QUEENS],inty){
for(intx=0;xm[0][x][y]=1;
if(wy_isOk(m,x,y,0)){
if(y==QUEENS-1){
//print(m,0);
}else
wy_serial_listAllCol(m,y+1);
}
m[0][x][y]=0;
}
}
/**
*wy_parallel_listOtherCol:
DetermineTheOtherColsInParallelWay
*
*@paramm[][][]
*@paramy
*@paramthread
*/
staticvoidwy_parallel_listOtherCol(intm[THREADS][QUEENS][QUEENS],inty,intthread){
for(intx=0;xm[thread][x][y]=1;
if(wy_isOk(m,x,y,thread)){
if(y==QUEENS-1){
//print(m,thread);
}else
wy_parallel_listOtherCol(m,y+1,thread);
}
m[thread][x][y]=0;
}
}
/**
*wy_parallel_listFirstCol:
DetermineTheFirstColInParallelWay
*
*@paramm[][][]
*@paramy
*/
staticvoidwy_parallel_listFirstCol(intm[THREADS][QUEENS][QUEENS],inty,intthread){
intfloorLength=int(floor(double(QUEENS/2)));
if(thread==0){
for(intx=0;xm[thread][x][y]=1;
if(wy_isOk(m,x,y,thread)){
wy_parallel_listOtherCol(m,y+1,thread);
}
m[thread][x][y]=0;
}
}else{
for(intx=floorLength;xm[thread][x][y]=1;
if(wy_isOk(m,x,y,thread)){
wy_parallel_listOtherCol(m,y+1,thread);
}
m[thread][x][y]=