[Beowulf] OpenMP on AMD dual core processors

Joe Landman landman at scalableinformatics.com
Thu Nov 20 20:55:24 PST 2008


Nathan Moore wrote:

> Any suggestions?  I figured that this would be a simple example to 
> parallelize.  Is there a better example for OpenMP parallelization?  
> Also, is there something obvious I'm missing in the example below? 

A few thoughts ...

Initialize your data in parallel as well.  No reason not to.  But 
optimize that code a bit.  You don't need

	v_y = v_ground + (v_cloud-v_ground)*(j*dy/Ly)
        	boundary(i,j)=0
       	v(i,j) = v_y

when

	v(i,j)=  v_ground + (v_cloud-v_ground)*(j*dy/Ly)
        	boundary(i,j)=0

will eliminate the explicit temporary variable.  Also the i.eq.0 test is 
guaranteed never to be hit in the if-then construct, as with the j.eq.0.

You can (and should) replace that if-then construct with a set of loops 
of the form

	do j=1,Ny
	 boundary(Nx,j) = 1
	end do      	
	do i=1,Nx
	 boundary(i,Ny) = 1
	end do

Also, what sticks out to me is that old_v may be viewed as "shared" 
versus "private".  I know OpenMP is supposed to do the right thing here, 
  but you might need to explicitly mark old_v as private.  And dv for 
that matter.

Note also that this inner loop is attempting to do a convergence test. 
You are looking to set a globally shared value from within an inner 
loop.  This is not a good thing to do.  This means accesses to that 
globally shared variable are going to be locked.

I would suggest a slightly different inner loop and convergence test: 
(note ... this relies on something I havent tried in fortran so 
adjustment may be needed)


real*8 vnew(Nx,Ny),dv(Nx,Ny)

do i=1,Nx
  do j=1,Ny
     ! notice that the if-then construct is gone ...
     ! vnew eq 0.0 for boundaries
     vnew(i,j) = 0.25*(v(i-1,j)+v(i+1,j)+v(i,j+1)+v(i,j-1))*
		dabs(boundary(i,j).eq.0)
     dv(i,j) = (dabs(v(i,j)-vnew(i,j)) - convergence_v )* 
dabs(boundary(i,j).eq.0)
  end do
end do

! now all you need is a "linear scan" to find positive elements in
! dv.  You can approach these as sum reductions, and do them in
! parallel
do i=1,Nx
  sum=0.0
  do j=1,Ny
   sum = sum + dabs(dv(i,j) .gt. 0.0) * dv(i,j)
  end do
  if (sum .gt. 0.0) converged = 0
end do

The basic idea is to replace the inner loop conditionals and remove as 
many of the shared variables as possible.

Also c.f. examples here:  http://www.linux-mag.com/id/4609  specifically 
the Riemann zeta function (fairly trivial).



-- 
Joseph Landman, Ph.D
Founder and CEO
Scalable Informatics LLC,
email: landman at scalableinformatics.com
web  : http://www.scalableinformatics.com
        http://jackrabbit.scalableinformatics.com
phone: +1 734 786 8423 x121
fax  : +1 866 888 3112
cell : +1 734 612 4615



More information about the Beowulf mailing list