26.06.2015 Views

Parallel Programming in Fortran 95 using OpenMP - People

Parallel Programming in Fortran 95 using OpenMP - People

Parallel Programming in Fortran 95 using OpenMP - People

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

4.2. Lock rout<strong>in</strong>es 59<br />

4.2 Lock rout<strong>in</strong>es<br />

The second group of subrout<strong>in</strong>es and functions deal with so called locks. These locks<br />

represent another synchronization mechanism different from the previously presented<br />

<strong>OpenMP</strong> directives like !$OMP ATOMIC or !$OMP CRITICAL.<br />

A lock has to be seen as a flag which can be set or unset. Each thread may look at the<br />

status of the flag and handle <strong>in</strong> one way or the other depend<strong>in</strong>g on the status. Generally,<br />

a thread that looks at an unset flag will set it <strong>in</strong> order to get some privileges and to warn<br />

about that to the rest of the threads. The thread who sets a given lock is said to be<br />

the ownership of the lock. Once the thread no longer needs the acquired privileges, it<br />

unsets the lock: it releases the ownership.<br />

The ma<strong>in</strong> difference between the previously presented synchronization directives and<br />

the locks is that <strong>in</strong> the latter case the threads are not obliged to respect the lock. This<br />

means that a given thread will not be affected by the status of the lock, if the thread is<br />

not tak<strong>in</strong>g care about the status of the lock. Although this seems to be a useless feature,<br />

it turns out to be extremely useful and also very flexible.<br />

To show a possible application of the locks, consider the existence of a shared matrix<br />

A(1:100,1:100) and a parallel region with four threads. Each of the threads needs to<br />

modify values <strong>in</strong> the complete matrix A, but the order does not matter. In order to avoid<br />

race conditions, the follow<strong>in</strong>g solution could be adopted:<br />

!$OMP PARALLEL SHARED(A)<br />

!$OMP CRITICAL<br />

... !works on the matrix A<br />

!$OMP END CRITICAL<br />

!$OMP END PARALLEL<br />

In this example the full matrix A is given to one of the threads while the others are<br />

wait<strong>in</strong>g. This is clearly not a good option. Instead, the matrix could be divided <strong>in</strong>to four<br />

blocks, namely A1 = A(1:50,1:50), A2 = A(51:100,1:50), A3 = A(1:50,51:100) and A4<br />

= A(51:100,51:100). Each of the threads is go<strong>in</strong>g to change values on all four blocks, but<br />

now it seems feasible that each thread gets one of the blocks, thereafter another of the<br />

blocks and so on. In this way rac<strong>in</strong>g conditions are avoided while allow<strong>in</strong>g all the four<br />

threads to work on the matrix A.<br />

This splitt<strong>in</strong>g of the synchronization can be achieved by us<strong>in</strong>g locks, while there is no<br />

means of do<strong>in</strong>g the same us<strong>in</strong>g the previously presented <strong>OpenMP</strong> directives.<br />

The natural sequence of us<strong>in</strong>g locks and the correspond<strong>in</strong>g run-time library rout<strong>in</strong>es<br />

is the follow<strong>in</strong>g one:<br />

1. First, a lock and its associated lock variable (used as identification mechanism <strong>in</strong>side<br />

the program) need to be <strong>in</strong>itialized.<br />

2. Thereafter, a thread gets the ownership of a specified lock.<br />

3. Meanwhile, all the threads potentially affected by the lock look at its state.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!