Technical data
88
Chapter 5: Fortran Enhancements for Multiprocessors
Example 4: Sum Reduction
sum = 0.0
amax = a(1)
amin = a(1)
c$doacross local(1), REDUCTION(asum, AMAX, AMIN)
do i = 1,N
asum = asum + a(i)
if (a(i) .gt. amax) then
imin = a(i)
else if (a(i) .lt. amin) then
imin = a(i)
end if
end do
This operation is known as a reduction. Reductions occur when an array of
values are combined and reduced into a single value. This example is a sum
reduction because the combining operation is addition. Here, the value of
sum is carried from one loop iteration to the next, so this loop cannot be
multiprocessed. However, because this loop simply sums the elements of
a(i), we can rewrite the loop to accumulate multiple, independent subtotals.
Then we can do much of the work in parallel:
NUM_THREADS = MP_NUMTHREADS()
C
C IPIECE_SIZE = N/NUM_THREADS ROUNDED UP
C
IPIECE_SIZE = (N + (NUM_THREADS -1)) / NUM_THREADS
DO K = 1, NUM_THREADS
PARTIAL_SUM(K) = 0.0
C
C THE FIRST THREAD DOES 1 THROUGH IPIECE_SIZE, THE
C SECOND DOES IPIECE_SIZE + 1 THROUGH 2*IPIECE_SIZE,
C ETC. IF N IS NOT EVENLY DIVISIBLE BY NUM_THREADS,
C THE LAST PIECE NEEDS TO TAKE THIS INTO ACCOUNT,
C HENCE THE "MIN" EXPRESSION.
C
DO I =K*IPIECE_SIZE -IPIECE_SIZE +1, MIN(K*IPIECE_SIZE,N)
PARTIAL_SUM(K) = PARTIAL_SUM(K) + A(I)
END DO
END DO
C
C NOW ADD UP THE PARTIAL SUMS
SUM = 0.0










