source: CIVL/examples/pthread/llnl/mpithreads_threads.c@ e2570cd

main test-branch
Last change on this file since e2570cd was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 4.6 KB
RevLine 
[a6e9777]1/*****************************************************************************
2* FILE: mpithreads_threads.c
3* DESCRIPTION:
4* This simple program illustrates the use of Pthreads in a program obtained
5* by modifying a serial code that performs a dot product. It is the second
6* of four codes used to show the progression from a serial program to a
7* hybrid MPI/Pthreads program. The other relevant codes are:
8* - mpithreads_serial.c - The serial version
9* - mpithreads_mpi.c - A distributed memory programming model with MPI
10* - mpithreads_both.c - A hybrid model that utilizes both MPI and
11* Pthreads to execute on systems that are comprised of clusters
12* of SMP's.
13* The main data is made available to all threads through a globally
14* accessible structure. Each thread works on a different part of the
15* data. The main thread waits for all the threads to complete their
16* computations, and then it prints the resulting sum.
17* SOURCE: Vijay Sonnad, IBM
18* LAST REVISED: 01/29/09 Blaise Barney
19******************************************************************************/
20#include <pthread.h>
21#include <stdio.h>
22#include <stdlib.h>
23
24/*
25The following structure contains the necessary information to allow the
26function "dotprod" to access its input data and place its output into
27the structure. This structure is unchanged from the sequential version.
28*/
29
30typedef struct
31 {
32 double *a;
33 double *b;
34 double sum;
35 int veclen;
36 } DOTDATA;
37
38/* Define globally accessible variables and a mutex */
39
40#define MAXTHRDS 3
41#define VECLEN 10
42DOTDATA dotstr;
43pthread_t callThd[MAXTHRDS];
44pthread_mutex_t mutexsum;
45
46/*
47The function dotprod is activated when the thread is created. As before,
48all input to this routine is obtained from a structure of type DOTDATA and
49all output from this function is written into this structure. The benefit
50of this approach is apparent for the multi-threaded program: when a thread
51is created we pass a single argument to the activated function - typically
52this argument is a thread number. All the other information required by the
53function is accessed from the globally accessible structure.
54*/
55
56void *dotprod(void *arg)
57{
58
59 /* Define and use local variables for convenience */
60
61 int i, start, end, len ;
62 long offset;
63 double mysum, *x, *y;
64 offset = (long)arg;
65
66 len = dotstr.veclen;
67 start = offset*len;
68 end = start + len;
69 x = dotstr.a;
70 y = dotstr.b;
71
72 /*
73 Perform the dot product and assign result to the appropriate variable in
74 the structure.
75 */
76
77 mysum = 0;
78 for (i=start; i<end ; i++)
79 {
80 mysum += (x[i] * y[i]);
81 }
82
83 /*
84 Lock a mutex prior to updating the value in the shared structure, and
85 unlock it upon updating.
86 */
87 pthread_mutex_lock (&mutexsum);
88 printf("Thread %ld adding partial sum of %f to global sum of %f\n",
89 offset, mysum, dotstr.sum);
90 dotstr.sum += mysum;
91 pthread_mutex_unlock (&mutexsum);
92
93 //pthread_exit((void*) 0);
94}
95
96/*
97The main program creates threads which do all the work and then print out
98result upon completion. Before creating the threads, the input data is
99created. Since all threads update a shared structure, we need a mutex for
100mutual exclusion. The main thread needs to wait for all threads to complete,
101it waits for each one of the threads. We specify a thread attribute value
102that allow the main thread to join with the threads it creates. Note also
103that we free up handles when they are no longer needed.
104*/
105
106int main (int argc, char *argv[])
107{
108long i;
109double *a, *b;
110void *status;
111pthread_attr_t attr;
112
113/* Assign storage and initialize values */
114a = (double*) malloc (MAXTHRDS*VECLEN*sizeof(double));
115b = (double*) malloc (MAXTHRDS*VECLEN*sizeof(double));
116
117for (i=0; i<VECLEN*MAXTHRDS; i++) {
118 a[i]=1;
119 b[i]=a[i];
120 }
121
122dotstr.veclen = VECLEN;
123dotstr.a = a;
124dotstr.b = b;
125dotstr.sum=0;
126
127pthread_mutex_init(&mutexsum, NULL);
128
129/* Create threads to perform the dotproduct */
130pthread_attr_init(&attr);
131pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
132
133for(i=0;i<MAXTHRDS;i++) {
134 /* Each thread works on a different set of data.
135 The offset is specified by 'i'. The size of
136 the data for each thread is indicated by VECLEN.
137 */
138 pthread_create( &callThd[i], &attr, dotprod, (void *)i);
139 }
140
141pthread_attr_destroy(&attr);
142
143/* Wait on the other threads */
144for(i=0;i<MAXTHRDS;i++) {
145 pthread_join( callThd[i], &status);
146 }
147
148/* After joining, print out the results and cleanup */
149printf ("Done. Threaded version: sum = %f \n", dotstr.sum);
150free (a);
151free (b);
152pthread_mutex_destroy(&mutexsum);
153//pthread_exit(NULL);
154}
155
Note: See TracBrowser for help on using the repository browser.