Online Book Reader

Home Category

High Performance Computing - Charles Severance [85]

By Root 1267 0
me=%d - sleeping %d seconds ...\n", me, me+1);

sleep(me+1);

printf("SpinFunc me=%d – wake globvar=%d...\n", me, globvar);

globvar ++;

printf("SpinFunc me=%d - spinning globvar=%d...\n", me, globvar);

while(globvar < THREAD_COUNT ) ;

printf("SpinFunc me=%d – done globvar=%d...\n", me, globvar);

sleep(THREAD_COUNT+1);

}

If you look at the function, each thread entering this function prints a message and goes to sleep for 1, 2, and 3 seconds. Then the function increments globvar (initially set to 0 in main) and begins a while-loop, continuously checking the value of globvar. As time passes, the second and third threads should finish their sleep( ), increment the value for globvar, and begin the while-loop. When the last thread reaches the loop, the value for globvar is 3 and all the threads exit the loop. However, this isn’t what happens:

recs % create2 &

[1] 23921

recs %

Main - globvar=0

Main - creating i=0 tid=4 retval=0

Main - creating i=1 tid=5 retval=0

Main - creating i=2 tid=6 retval=0

Main thread - threads started globvar=0

Main - waiting for join 4

SpinFunc me=0 - sleeping 1 seconds ...

SpinFunc me=1 - sleeping 2 seconds ...

SpinFunc me=2 - sleeping 3 seconds ...

SpinFunc me=0 - wake globvar=0...

SpinFunc me=0 - spinning globvar=1...

recs % ps

PID TTY TIME CMD

23921 pts/35 0:09 create2

recs % ps

PID TTY TIME CMD

23921 pts/35 1:16 create2

recs % kill -9 23921

[1] Killed create2

recs %

We run the program in the background[56] and everything seems to run fine. All the threads go to sleep for 1, 2, and 3 seconds. The first thread wakes up and starts the loop waiting for globvar to be incremented by the other threads. Unfortunately, with user space threads, there is no automatic time sharing. Because we are in a CPU loop that never makes a system call, the second and third threads never get scheduled so they can complete their sleep( ) call. To fix this problem, we need to make the following change to the code:

while(globvar < THREAD_COUNT ) sleep(1) ;

With this sleep[57] call, Threads 2 and 3 get a chance to be “scheduled.” They then finish their sleep calls, increment the globvar variable, and the program terminates properly.

You might ask the question, “Then what is the point of user space threads?” Well, when there is a high performance database server or Internet server, the multiple logical threads can overlap network I/O with database I/O and other background computations. This technique is not so useful when the threads all want to perform simultaneous CPU-intensive computations. To do this, you need threads that are created, managed, and scheduled by the operating system rather than a user library.


Operating System-Supported Multithreading

When the operating system supports multiple threads per process, you can begin to use these threads to do simultaneous computational activity. There is still no requirement that these applications be executed on a multiprocessor system. When an application that uses four operating system threads is executed on a single processor machine, the threads execute in a time-shared fashion. If there is no other load on the system, each thread gets 1/4 of the processor. While there are good reasons to have more threads than processors for noncompute applications, it’s not a good idea to have more active threads than processors for compute-intensive applications because of thread-switching overhead. (For more detail on the effect of too many threads, see Appendix D, How FORTRAN Manages Threads at Runtime.

If you are using the POSIX threads library, it is a simple modification to request that your threads be created as operating-system rather rather than user threads, as the following code shows:

#define _REENTRANT /* basic 3-lines for threads */

#include

#include

#define THREAD_COUNT 2

void *SpinFunc(void *);

int globvar; /* A global variable */

int index[THREAD_COUNT]; /* Local zero-based thread index */

pthread_t thread_id[THREAD_COUNT]; /* POSIX Thread IDs */

pthread_attr_t attr; /* Thread attributes

Return Main Page Previous Page Next Page

®Online Book Reader