any advice???

General OpenMP discussion

any advice???

Postby c-- » Fri Dec 12, 2008 1:05 pm

I am beginner in OpenMP, and I need some advice. How can I parallel this in OpenMP:
method dct_setc a dct_row I call in method dct
void dct_setc(double *c,int n)
{
int a;
double i,j;
a=0;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
c[a] =cos((M_PI/n)*i*(j+0.5));
a++;
}
}

void dct_row(double *dst,double *src,int n,double *c)
{
int i,j,a;
double sum,c0;
c0=src[0]/double(n);
a=0;
for(i=0;i<n;i++)
{
sum=c0;
for(j=0;j<n;j++)
{
sum += src[j]*c[a];
a++;
}
dst[i] = sum;
}
}

//input 2D arrays , with size, and output is 2D arrays
void dct(double **dst,double **src,int xs,int ys)
{
int x,y;
double *c,**m,**n;

m=new double*[xs]; for (y=0;y<xs;y++) m[y]=new double[ys];
n=new double*[xs]; for (y=0;y<xs;y++) n[y]=new double[ys];
c=new double[xs*xs];

dct_setc(c,xs);
for(y=0;y<ys;y++) dct_row(dst[y],src[y],xs,c);
delete c;

for (y=0;y<ys;y++)
for (x=0;x<xs;x++)
m[x][y]=src[y][x];

c=new double[ys*ys];
dct_setc(c,ys);
for(y=0;y<xs;y++) dct_row(n[y],m[y],ys,c);
delete c;

for (y=0;y<ys;y++)
for (x=0;x<xs;x++)
dst[y][x]=n[x][y];

for (y=0;y<xs;y++) delete[] m[y]; delete m;
for (y=0;y<xs;y++) delete[] n[y]; delete n;
}


Thank for any advice. ;)
c--
 

Re: any advice???

Postby ejd » Fri Dec 12, 2008 4:32 pm

There are two problems here. One is that you haven't given me enough information to know whether it is worth it to parallelize any of the loops. Of course, this is really very machine specific (depending on cache, architecture, etc), so you really have to determine that yourself. Second, I really am not in the business of doing everyone else's work. I have no idea if this is someone's homework problem, thesis project, or play toy.

That said, I will try and point you in the right direction. The loops in function dct can easily be run in parallel as follows:
Code: Select all
#pragma omp parallel private(x, y)
for (y=0;y<ys;y++)
  for (x=0;x<xs;x++)
  ...

The loops in function dct_setc and functon dct_row can easily be parallelized if you can get rid of index "a" and express the index instead in terms of I' and "j".
ejd
 
Posts: 1025
Joined: Wed Jan 16, 2008 7:21 am

Re: any advice???

Postby c-- » Sat Dec 13, 2008 2:51 am

ejd wrote:There are two problems here. One is that you haven't given me enough information to know whether it is worth it to parallelize any of the loops. Of course, this is really very machine specific (depending on cache, architecture, etc), so you really have to determine that yourself. Second, I really am not in the business of doing everyone else's work. I have no idea if this is someone's homework problem, thesis project, or play toy.

That said, I will try and point you in the right direction. The loops in function dct can easily be run in parallel as follows:
Code: Select all
#pragma omp parallel private(x, y)
for (y=0;y<ys;y++)
  for (x=0;x<xs;x++)
  ...

The loops in function dct_setc and functon dct_row can easily be parallelized if you can get rid of index "a" and express the index instead in terms of I' and "j".


I have new PC with 2 core...it s all , i want learn something abou OpenMP
This isn t homework, project... etc... Sory , I want only advice
c--
 

Re: any advice???

Postby ejd » Mon Dec 15, 2008 9:45 am

I gave you enough information that this should be easy to parallelize - though I doubt it will have enough work to be worth it. Give it a try and if you have more specific questions, I will be glad to help.
ejd
 
Posts: 1025
Joined: Wed Jan 16, 2008 7:21 am

Re: any advice???

Postby c-- » Tue Dec 16, 2008 10:21 am

I try this solution, but something is wrong,can you tell me what us wrong ???:
I try make loop parallel in function fun1, and fun1 is call in fun2, fun is method from my class
void fun1(double *dst,double *src,int n)
{
double sum,xk,c;
int i,j;
#pragma omp parallel private(i,j)
#pragma omp parallel for schedule(dynamic, 20)// chunk size =20
for(i=0; i<n; i++)
{
sum = 0;
for(j=0; j<n; j++)
{
c = (Math::PI/n)*i*(j+0.5);
sum +=src[j] * Math::Cos(c);
}
dst[i] = sum;
}
#pragma omp barrier
}
//---------------------------------------------------------------------------
void Parallel::fun2(double **dst,double **src,int w,int h)
{
int x,y;
double *c,**m,**n;

m=new double*[w];
for (y=0;y<w;y++) m[y]=new double[h];

n=new double*[w];
for (y=0;y<w;y++)
n[y]=new double[h];

for(y=0;y<h;y++)
fun1(dst[y],src[y],w);

for (y=0;y<h;y++)
for (x=0;x<w;x++)
m[x][y]=src[y][x];

for(y=0;y<w;y++)
fun1(n[y],m[y],h);

for (y=0;y<h;y++)
for (x=0;x<w;x++)
dst[y][x]=n[x][y];

for (y=0;y<w;y++)
delete[] m[y];
delete m;

for (y=0;y<w;y++)
delete[] n[y];
delete n;
}
c--
 

Re: any advice???

Postby ejd » Wed Dec 17, 2008 7:05 am

Lets look at the parallel code you wrote and see if it works.
Code: Select all
1  void fun1(double *dst,double *src,int n)
2  {
3    double sum,xk,c;
4    int i,j;
5    #pragma omp parallel private(i,j)
6    #pragma omp parallel for schedule(dynamic, 20)// chunk size =20
7    for(i=0; i<n; i++)
8    {
9      sum = 0;
10      for(j=0; j<n; j++)
11      {
12        c = (Math::PI/n)*i*(j+0.5);
13        sum +=src[j] * Math::Cos(c);
14      }
15      dst[i] = sum;
16    }
17    #pragma omp barrier
18  }

The first problem is on lines 5 and 6. You have specified "parallel" for both. This means that a parallel region will be created for the first one on line 5 and then a new one will be created for the one on line 6. The outer one (on line 5) doesn't do any work other than privatizing the variables "i" and "j" - which the inner region doesn't see. That means that the for loop at loop 10 will have a shared loop index and this is wrong. Only one of these should specify parallel.

The other note is that unless you have some reason to use "schedule(dynamic, 20)", I would suggest using "schedule(static)". The static schedule doesn't have quite as much overhead. Also letting the size of the chunk default so that there is only one pass through the loop to schedule threads is usually good for performance as well. Once you get it working, you can play with this and maybe see what I mean. It will depend on how much work you have to do as to whether you will see the difference or not.

Next the barrier at line 17 is not needed and should be removed. The parallel region has an implicit barrier at the end of the region (which ends at line 17). That means that you effectively have a barrier followed by a barrier, which some compilers will optimize out and some won't (since the second one isn't even in a parallel region). While it will work, you don't need it so you might as well remove it and save some overhead.

Now to the code itself. You have two problems - variable "c" and "sum". I will address "c" and hopefully you will see the problem for "sum". You set the value of "c" on line 12 and use it on line 13. The variable "c" is defined on line 3 and you don't have it in any clause on the parallel region, so by default it is shared. That means that if you were running with 2 threads, that the first thread could set the value of "c" on line 12 and before it could execute line 13, that the second thread could reset the value of "c". Now when line 13 is executed, both have the same value for "c" - which is not what you wanted.

So now your code should look something like:
Code: Select all
1  void fun1(double *dst,double *src,int n)
2  {
3    double sum,xk,c;
4    int i,j;
5    #pragma omp parallel for schedule(static) private(i, j, c)
6    for(i=0; i<n; i++)
7    {
8      sum = 0;                          // sum still is a problem and needs to be fixed
9      for(j=0; j<n; j++)
10     {
11        c = (Math::PI/n)*i*(j+0.5);
12        sum +=src[j] * Math::Cos(c);
13     }
14     dst[i] = sum;
15   }
16  }

Note that "sum" is still a problem and needs to be fixed and is slightly more complicated than the fix for "c".
ejd
 
Posts: 1025
Joined: Wed Jan 16, 2008 7:21 am

Re: any advice???

Postby c-- » Wed Dec 17, 2008 11:13 am

ejd thank you, your advices are helpful. I am beginner in OpenMP a next 3-4 days i will study very hard ;) I try find solution form "sum". The OpenMP is goog way to increase speed up my application....
c--
 


Return to Using OpenMP

Who is online

Users browsing this forum: No registered users and 1 guest

cron