主题:OpenMP并行之后反而变慢了,高人给看看吧,不胜感激...
[code=c]
/************************************************************************/
/* Conway's Game of Life */
/* */
/* 1. Any live cell with fewer than two live neighbors dies, as if */
/* caused by under-population. */
/* 2. Any live cell with two or three live neighbors lives on to the */
/* next generation. */
/* 3. Any live cell with more than three live neighbors dies, as if */
/* by overcrowding. */
/* 4. Any dead cell with exactly three live neighbors becomes a */
/* */
/* Date: 30 May 2012 */
/* Author: ThreeSZO */
/************************************************************************/
#include <graphics.h>
#include <conio.h>
#include <omp.h>
#include <stdio.h>
#define CELL_HEIGHT 10 //cell`s height
#define CELL_WIDTH 10 //cell`s width
#define NUMBEROFCELL_HORIZONTAL 120 //cell`s number at horizontal
#define NUMBEROFCELL_VERTICAL 60 //cell`s number at vertical
//storage cell`s state
//0 dead black
//1 live white
//2 will die red
//3 will live green
char _gameOfLife[NUMBEROFCELL_HORIZONTAL][NUMBEROFCELL_VERTICAL] = {0};
//use this array to calculate neighbors coordinate of the cell
char _cellNeighbors[8][2] =
{{-1,-1},{ 0,-1},{+1,-1},
{-1, 0},/*cell*/{+1, 0},
{-1,+1},{0,+1},{+1,+1}};
MOUSEMSG _myMouse; //mouse state
bool isRun = false; //flag of game running
int CalcNeighbors(int,int);
void CalcLife();
void GetControl();
//main function
void main()
{
initgraph(NUMBEROFCELL_HORIZONTAL * CELL_WIDTH, NUMBEROFCELL_VERTICAL * CELL_HEIGHT); //initialize the graph
omp_set_dynamic(0); //disallow dynamic
omp_set_nested(1); //allow nested
//omp_set_num_threads(2); //set the number of threads
#pragma omp parallel sections num_threads(2)
{
#pragma omp section
{
GetControl();
}
#pragma omp section
{
CalcLife();
}
}
getch(); //press any button to return
closegraph(); //close the graph
}
//get control from mouse
void GetControl()
{
int x,y;
long int count = 0;
while(!isRun)
{
if(MouseHit() == true)
_myMouse = GetMouseMsg(); //get a message from mouse
switch(_myMouse.uMsg)
{
case WM_LBUTTONDOWN:
if(isRun == false)
{
x = _myMouse.x / 10;
y = _myMouse.y / 10;
_gameOfLife[x][y] = 1; //put the cell to be live
setfillstyle(WHITE,SOLID_FILL,NULL);
bar(x * CELL_WIDTH, y * CELL_HEIGHT,
(x + 1) * CELL_WIDTH -1, (y + 1) * CELL_HEIGHT -1); //draw the cell
}
break;
case WM_MBUTTONUP:
if(isRun == false)
isRun = true;
else
isRun = false;
//Sleep(500);
break;
default:
break;
}
}
}
//calculate neighbors around cell
int CalcNeighbors(int x, int y)
{
int _x = x,
_y = y;
int _numberOfNeighbors = 0;
for(int i = 0; i < 8; ++i)
{
_x = x + _cellNeighbors[i][0];
_y = y + _cellNeighbors[i][1];
if(_x < 0)
_x = NUMBEROFCELL_HORIZONTAL - 1;
else if(_x > NUMBEROFCELL_HORIZONTAL - 1)
_x = 0;
if(_y < 0)
_y = NUMBEROFCELL_VERTICAL - 1;
else if(_y > NUMBEROFCELL_VERTICAL - 1)
_y = 0;
if(_gameOfLife[_x][_y] == 1 || _gameOfLife[_x][_y] == 2)
_numberOfNeighbors++;
if(_numberOfNeighbors > 3) //if neighbors greater than 3,then break out
break;
}
return _numberOfNeighbors;
}
//calculate the next generation
void CalcLife()
{
int count = 0;
int i,j,k;
double startTime,endTime;
FILE *fp1;
fp1 = fopen("test1.txt","w");
while(!isRun) //wait the start signal
;
startTime = omp_get_wtime();
for(count = 0;count < 1000; count++)
{
if(isRun == true)
{
#pragma omp parallel for private(j)
for(i = 0; i < NUMBEROFCELL_HORIZONTAL; i++)
for(j = 0; j < NUMBEROFCELL_VERTICAL; j++)
{
if(_gameOfLife[i][j] == 2)
_gameOfLife[i][j] = 0;
else if(_gameOfLife[i][j] == 3)
_gameOfLife[i][j] = 1;
}
#pragma omp parallel for private(j,k)
for(i = 0; i < NUMBEROFCELL_HORIZONTAL; i++)
for(j = 0; j < NUMBEROFCELL_VERTICAL; j++)
{
k = CalcNeighbors(i,j);
switch(k)
{
case 2:
break;
case 3:
if(_gameOfLife[i][j] == 0)
{
_gameOfLife[i][j] = 3;
setfillstyle(WHITE,SOLID_FILL,NULL);
bar(i * CELL_WIDTH, j * CELL_HEIGHT,
(i + 1) * CELL_WIDTH -1, (j + 1) * CELL_HEIGHT -1); //draw the cell
}
break;
default:
if(_gameOfLife[i][j] == 1)
_gameOfLife[i][j] = 2;
setfillstyle(BLACK,SOLID_FILL,NULL);
bar(i * CELL_WIDTH, j * CELL_HEIGHT,
(i + 1) * CELL_WIDTH -1, (j + 1) * CELL_HEIGHT -1); //draw the cell
break;
}
}
}
//Sleep(100);
}
endTime = omp_get_wtime();
fprintf(fp1,"startTime = %.16g\nendTime = %016g\ndiff = %.16g\n",startTime,endTime,endTime - startTime);
fclose(fp1);
}
[/code]
生命游戏的并行,使用的OpenMP,但是并行之后比串行反而慢了,怎么改都不行,高人指点下,不胜感激.....
/************************************************************************/
/* Conway's Game of Life */
/* */
/* 1. Any live cell with fewer than two live neighbors dies, as if */
/* caused by under-population. */
/* 2. Any live cell with two or three live neighbors lives on to the */
/* next generation. */
/* 3. Any live cell with more than three live neighbors dies, as if */
/* by overcrowding. */
/* 4. Any dead cell with exactly three live neighbors becomes a */
/* */
/* Date: 30 May 2012 */
/* Author: ThreeSZO */
/************************************************************************/
#include <graphics.h>
#include <conio.h>
#include <omp.h>
#include <stdio.h>
#define CELL_HEIGHT 10 //cell`s height
#define CELL_WIDTH 10 //cell`s width
#define NUMBEROFCELL_HORIZONTAL 120 //cell`s number at horizontal
#define NUMBEROFCELL_VERTICAL 60 //cell`s number at vertical
//storage cell`s state
//0 dead black
//1 live white
//2 will die red
//3 will live green
char _gameOfLife[NUMBEROFCELL_HORIZONTAL][NUMBEROFCELL_VERTICAL] = {0};
//use this array to calculate neighbors coordinate of the cell
char _cellNeighbors[8][2] =
{{-1,-1},{ 0,-1},{+1,-1},
{-1, 0},/*cell*/{+1, 0},
{-1,+1},{0,+1},{+1,+1}};
MOUSEMSG _myMouse; //mouse state
bool isRun = false; //flag of game running
int CalcNeighbors(int,int);
void CalcLife();
void GetControl();
//main function
void main()
{
initgraph(NUMBEROFCELL_HORIZONTAL * CELL_WIDTH, NUMBEROFCELL_VERTICAL * CELL_HEIGHT); //initialize the graph
omp_set_dynamic(0); //disallow dynamic
omp_set_nested(1); //allow nested
//omp_set_num_threads(2); //set the number of threads
#pragma omp parallel sections num_threads(2)
{
#pragma omp section
{
GetControl();
}
#pragma omp section
{
CalcLife();
}
}
getch(); //press any button to return
closegraph(); //close the graph
}
//get control from mouse
void GetControl()
{
int x,y;
long int count = 0;
while(!isRun)
{
if(MouseHit() == true)
_myMouse = GetMouseMsg(); //get a message from mouse
switch(_myMouse.uMsg)
{
case WM_LBUTTONDOWN:
if(isRun == false)
{
x = _myMouse.x / 10;
y = _myMouse.y / 10;
_gameOfLife[x][y] = 1; //put the cell to be live
setfillstyle(WHITE,SOLID_FILL,NULL);
bar(x * CELL_WIDTH, y * CELL_HEIGHT,
(x + 1) * CELL_WIDTH -1, (y + 1) * CELL_HEIGHT -1); //draw the cell
}
break;
case WM_MBUTTONUP:
if(isRun == false)
isRun = true;
else
isRun = false;
//Sleep(500);
break;
default:
break;
}
}
}
//calculate neighbors around cell
int CalcNeighbors(int x, int y)
{
int _x = x,
_y = y;
int _numberOfNeighbors = 0;
for(int i = 0; i < 8; ++i)
{
_x = x + _cellNeighbors[i][0];
_y = y + _cellNeighbors[i][1];
if(_x < 0)
_x = NUMBEROFCELL_HORIZONTAL - 1;
else if(_x > NUMBEROFCELL_HORIZONTAL - 1)
_x = 0;
if(_y < 0)
_y = NUMBEROFCELL_VERTICAL - 1;
else if(_y > NUMBEROFCELL_VERTICAL - 1)
_y = 0;
if(_gameOfLife[_x][_y] == 1 || _gameOfLife[_x][_y] == 2)
_numberOfNeighbors++;
if(_numberOfNeighbors > 3) //if neighbors greater than 3,then break out
break;
}
return _numberOfNeighbors;
}
//calculate the next generation
void CalcLife()
{
int count = 0;
int i,j,k;
double startTime,endTime;
FILE *fp1;
fp1 = fopen("test1.txt","w");
while(!isRun) //wait the start signal
;
startTime = omp_get_wtime();
for(count = 0;count < 1000; count++)
{
if(isRun == true)
{
#pragma omp parallel for private(j)
for(i = 0; i < NUMBEROFCELL_HORIZONTAL; i++)
for(j = 0; j < NUMBEROFCELL_VERTICAL; j++)
{
if(_gameOfLife[i][j] == 2)
_gameOfLife[i][j] = 0;
else if(_gameOfLife[i][j] == 3)
_gameOfLife[i][j] = 1;
}
#pragma omp parallel for private(j,k)
for(i = 0; i < NUMBEROFCELL_HORIZONTAL; i++)
for(j = 0; j < NUMBEROFCELL_VERTICAL; j++)
{
k = CalcNeighbors(i,j);
switch(k)
{
case 2:
break;
case 3:
if(_gameOfLife[i][j] == 0)
{
_gameOfLife[i][j] = 3;
setfillstyle(WHITE,SOLID_FILL,NULL);
bar(i * CELL_WIDTH, j * CELL_HEIGHT,
(i + 1) * CELL_WIDTH -1, (j + 1) * CELL_HEIGHT -1); //draw the cell
}
break;
default:
if(_gameOfLife[i][j] == 1)
_gameOfLife[i][j] = 2;
setfillstyle(BLACK,SOLID_FILL,NULL);
bar(i * CELL_WIDTH, j * CELL_HEIGHT,
(i + 1) * CELL_WIDTH -1, (j + 1) * CELL_HEIGHT -1); //draw the cell
break;
}
}
}
//Sleep(100);
}
endTime = omp_get_wtime();
fprintf(fp1,"startTime = %.16g\nendTime = %016g\ndiff = %.16g\n",startTime,endTime,endTime - startTime);
fclose(fp1);
}
[/code]
生命游戏的并行,使用的OpenMP,但是并行之后比串行反而慢了,怎么改都不行,高人指点下,不胜感激.....