Friday, January 28, 2011

Parallel Frameworks: Rampaging threads - Erecting an effective barrier

Rampaging threads - Erecting an effective barrier


Keywords: threads, semaphores, mutex, barrier, framework, Task Queue


Threads are independent units of execution. Notice that you can assign hard threads to work on hard problems and soft threads to other issues. Not all tasks are the same in terms of their hunger for CPU!

There is an occasional need to coordinate the entry of a team of threads into the next round of execution. Assuming each thread when let loose picks up the type of job that is designated for self or already has a job assigned to it that requires more than one round of execution.

The problem is to wait for all threads (a type of threads) to reach a designated barrier for the round and then let them loose to the next round! This may be required to setup or adjust the state prior to the next round of execution! For e.g., it may be the updated of a shared state variable or one that is referenced by all threads going into the next round!

An example is selection sort that requires the minimum for the next round to be adjusted prior to searching for a new minimum!

The Barrier object

My idea of a barrier is one where our thread that holds a reference to a ThreadObject finds a reference to a barrier object and calls either the synchronize() or barrierWait() function.

These two functions have a slightly different purpose, former is called by a worker thread and the later by a monitor thread. These function(s) do a few things!

a. Allow a thread to test a condition expression after holding a mutex!
b. Each thread that enters this testing condition manages to increment the thread count
at the barrier. When the last of the expected number of worker threads arrives at the barrier, this is signalled as an event. The barrier object is setup to expect nTeamThreads.
c. There is a monitor thread that waits on the last thread event! It sets up the state required to proceed to the next round. It flags all the worker threads to go ahead to the next round!

Notice the use of two events. One that effectively stops the rampaging threads from going any further until flagged by the monitor!

Monitor simply waits for the arrival of last thread at the barrier before setting up the state for the next round!

There is more code to be placed here.



class ThreadBarrier
{
public:
ThreadBarrier(int nSyncThreads) : _nSynchronizedThreads(nSyncThreads)
{
startupState();
};

virtual ~ThreadBarrier(void){
shutdownState();
};

bool synchronize(void){

bool syncComplete = false;
lock();

// condition expression test

unlock();

return syncComplete;
}

void reset_Barrier(void){
lock();

_nthreads_atBarrier = 0;

unlock();
}

void barrierWait(void){
WaitForSingleObject(_BarrierWaitEvent, INFINITE);
}
}


Here is Part I of the series of articles on Hands-on Programming for Parallelism using Multi-Cores

Here is Part II of the series of articles on How to assign a cpu core to a Thread?

Here is Part III of the series of articles on These Thread Libraries offer Help

Here is Part IV of the series of articles on Building Blocks of a Parallel Framwork

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home