Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] Annotation of /branches/vis12-cl/src/compiler/c-target/fragments/par-run.in
ViewVC logotype

Annotation of /branches/vis12-cl/src/compiler/c-target/fragments/par-run.in

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3226 - (view) (download)

1 : jhr 1826 /* Function which processes active strands. */
2 :     static void *@PREFIX@Worker (void *arg)
3 :     {
4 :     WorkerArg_t *myArg = (WorkerArg_t *)arg;
5 :     @PREFIX@World_t *wrld = myArg->wrld;
6 : jhr 2787 #ifndef DIDEROT_NO_GLOBALS
7 : jhr 1826 @PREFIX@Globals_t *glob = wrld->globals;
8 : jhr 2787 #endif
9 : jhr 1826 Diderot_Sched_t *sched = wrld->sched;
10 :     Strand_t *strand = &(wrld->strandDesc[0]);
11 :    
12 : jhr 1828 int nStrandsPerWorker = wrld->numStrands / sched->numWorkers;
13 : jhr 1826 int start = myArg->id * nStrandsPerWorker;
14 :     int limit;
15 :     if (sched->numWorkers-1 == myArg->id)
16 :     limit = wrld->numStrands;
17 :     else
18 :     limit = start + nStrandsPerWorker;
19 :    
20 : jhr 1831 while (true) {
21 : jhr 1826 // barrier synchronization at start of super step
22 :     pthread_mutex_lock (&sched->lock);
23 :     if (sched->numIdle+1 < sched->numWorkers) {
24 :     sched->numIdle++;
25 :     pthread_cond_wait (&sched->barrier, &sched->lock);
26 :     }
27 :     else {
28 :     // all other workers are idle, so we can proceed after some initialization
29 :     sched->numIdle = 0;
30 : jhr 1828 sched->numAvail = wrld->numStrands; // includes inactive strands
31 : jhr 1826 sched->nextStrand = 0;
32 : jhr 2082 #ifdef DIDEROT_DUAL_STATE
33 : jhr 1826 // swap in and out
34 : jhr 1828 @STRANDTY@ **tmp = wrld->inState;
35 : jhr 1827 wrld->inState = wrld->outState;
36 :     wrld->outState = tmp;
37 : jhr 2082 #endif
38 : jhr 1826 pthread_cond_broadcast (&sched->barrier);
39 :     }
40 :     pthread_mutex_unlock (&sched->lock);
41 :    
42 : jhr 1831 // if there are no active strands left or we've hit the maximum number of steps, then we're done
43 :     if ((sched->numActive == 0) || (sched->numSteps >= myArg->maxNSteps)) {
44 : jhr 1828 pthread_cond_signal (&sched->runWait);
45 : jhr 1826 pthread_exit (0);
46 :     }
47 :    
48 :     // iterate until there is no more work to do
49 :     int blkStart, blkSize;
50 :     int numDead = 0;
51 :     do {
52 :     // grab some work
53 :     pthread_mutex_lock (&sched->lock);
54 :     blkStart = sched->nextStrand;
55 :     blkSize = (sched->numAvail >= BLOCK_SIZE) ? BLOCK_SIZE : sched->numAvail;
56 :     sched->numAvail -= blkSize;
57 :     sched->nextStrand += blkSize;
58 :     pthread_mutex_unlock (&sched->lock);
59 :     // update the strands
60 :     for (int i = blkStart; i < blkStart+blkSize; i++) {
61 :     if (! wrld->status[i]) {
62 : jhr 2082 #ifdef DIDEROT_DUAL_STATE
63 : jhr 2787 # ifdef DIDEROT_NO_GLOBALS
64 : jhr 3081 StrandStatus_t sts = @STRAND@_Update(wrld->inState[i], wrld->outState[i]);
65 : jhr 2787 # else
66 : jhr 3081 StrandStatus_t sts = @STRAND@_Update(glob, wrld->inState[i], wrld->outState[i]);
67 : jhr 2787 # endif
68 : jhr 2082 #else
69 : jhr 2787 # ifdef DIDEROT_NO_GLOBALS
70 : jhr 3081 StrandStatus_t sts = @STRAND@_Update(&wrld->state[i]);
71 : jhr 2787 # else
72 : jhr 3081 StrandStatus_t sts = @STRAND@_Update(glob, &wrld->state[i]);
73 : jhr 2787 # endif
74 : jhr 2082 #endif
75 : jhr 1826 switch (sts) {
76 :     case DIDEROT_STABILIZE:
77 :     wrld->status[i] = DIDEROT_STABILIZE;
78 :     break;
79 :     case DIDEROT_DIE:
80 :     wrld->status[i] = DIDEROT_DIE;
81 :     numDead++;
82 :     break;
83 :     default:
84 :     break;
85 :     }
86 :     }
87 :     else {
88 :     assert ((wrld->status[i] == DIDEROT_STABLE) || (wrld->status[i] == DIDEROT_DIE));
89 :     }
90 :     }
91 :     } while (blkSize > 0);
92 :    
93 :     // barrier synchronization
94 :     pthread_mutex_lock (&sched->lock);
95 :     sched->numActive -= numDead;
96 :     if (sched->numIdle+1 < sched->numWorkers) {
97 :     sched->numIdle++;
98 :     pthread_cond_wait (&sched->barrier, &sched->lock);
99 :     }
100 :     else {
101 :     // all other workers are idle, so we can proceed
102 :     sched->numIdle = 0;
103 :     pthread_cond_broadcast (&sched->barrier);
104 : jhr 1828 sched->numSteps++;
105 : jhr 1826 }
106 :     pthread_mutex_unlock (&sched->lock);
107 :    
108 :     /**** If there is a global computation phase, it goes here ****/
109 :    
110 :     // stabilize any threads that need stabilization. Each worker is responsible for
111 :     // a contiguous region of the strands
112 :     // FIXME: once we switch to dynamic lists of strand blocks, then we can use finer-grain tracking
113 :     int numStabilized = 0;
114 :     for (int i = start; i < limit; i++) {
115 :     if (wrld->status[i] == DIDEROT_STABILIZE) {
116 : jhr 2082 #ifdef DIDEROT_DUAL_STATE
117 : jhr 1826 // stabilize the strand's state. Note that the outState has been set by
118 :     // the last call to update, so we make the inState be the target of the
119 :     // stabilize method.
120 : jhr 2787 # ifdef DIDEROT_NO_GLOBALS
121 : jhr 3081 @STRAND@_Stabilize(wrld->outState[i], wrld->inState[i]);
122 : jhr 2787 # else
123 : jhr 3081 @STRAND@_Stabilize(glob, wrld->outState[i], wrld->inState[i]);
124 : jhr 2787 # endif
125 : jhr 1826 memcpy (wrld->outState[i], wrld->inState[i], strand->stateSzb);
126 : jhr 2082 #else
127 : jhr 2787 # ifdef DIDEROT_NO_GLOBALS
128 : jhr 3081 @STRAND@_Stabilize(&wrld->state[i]);
129 : jhr 2787 # else
130 : jhr 3081 @STRAND@_Stabilize(glob, &wrld->state[i]);
131 : jhr 2787 # endif
132 : jhr 2082 #endif
133 : jhr 1826 wrld->status[i] = DIDEROT_STABLE;
134 :     numStabilized++;
135 :     }
136 :     }
137 :     // adjust the numActive count
138 :     #if defined(HAVE_BUILTIN_ATOMIC_OPS)
139 :     __sync_fetch_and_sub(&sched->numActive, numStabilized);
140 :     #else
141 :     pthread_mutex_lock (&sched->lock);
142 :     sched->numActive -= numStabilized;
143 :     pthread_mutex_unlock (&sched->lock);
144 :     #endif
145 : jhr 1828 } // end while
146 : jhr 1826
147 : jhr 1828 return 0;
148 :    
149 : jhr 1826 }
150 :    
151 :     //! Run the Diderot program (parallel version)
152 :     //! \param wrld the world-state of the Diderot program
153 :     //! \param maxNSteps the limit on the number of super steps; 0 means unlimited
154 : jhr 3226 //! \return the number of steps taken, or -1 on error.
155 : jhr 1826 uint32_t @PREFIX@Run (@PREFIX@World_t *wrld, uint32_t maxNSteps)
156 :     {
157 : jhr 2731 if (wrld->stage < POST_INITIALLY) {
158 : jhr 3226 biffMsgAdd (wrld->errors, "attempt to run uninitialized program\n");
159 :     return -1;
160 : jhr 2731 }
161 :     wrld->stage = RUNNING;
162 :    
163 : jhr 1826 Diderot_Sched_t *sched = wrld->sched;
164 :    
165 : jhr 1836 if (maxNSteps == 0) maxNSteps = 0xffffffff; // essentially unlimited
166 :    
167 : jhr 2769 double t0 = airTime();
168 :    
169 : jhr 1826 // Start worker threads
170 : jhr 1828 int nWorkers = sched->numWorkers;
171 : jhr 1826 WorkerArg_t *args = NEWVEC(WorkerArg_t, nWorkers);
172 :     if (wrld->verboseFlg) fprintf (stderr, "initializing %d workers ...\n", nWorkers);
173 :     double t0 = airTime();
174 :     sched->numWorkers = nWorkers;
175 :     sched->numIdle = 0;
176 : jhr 1828 sched->numSteps = 0;
177 : jhr 1826 for (int i = 0; i < nWorkers; i++) {
178 :     pthread_t pid;
179 :     args[i].wrld = wrld;
180 : jhr 1836 args[i].maxNSteps = maxNSteps;
181 : jhr 1826 args[i].id = i;
182 : jhr 3226 int sts = pthread_create (&pid, NULL, @PREFIX@Worker, (void *)&(args[i]));
183 :     if (sts != 0) {
184 :     biffMsgAddf (wrld->errors, "unable to create worker thread; err = %d\n", sts);
185 :     return -1;
186 : jhr 1826 }
187 :     pthread_detach (pid);
188 :     }
189 :    
190 :     // wait for the computation to finish
191 :     pthread_mutex_lock (&sched->lock);
192 : jhr 3081 while (sched->numIdle < nWorkers)
193 :     pthread_cond_wait (&sched->runWait, &sched->lock);
194 : jhr 1826 pthread_mutex_unlock (&sched->lock);
195 :    
196 : jhr 2769 t0 = airTime() - t0;
197 :     if (wrld->verboseFlg) {
198 :     fprintf (stderr, "done in %f seconds\n", t0);
199 :     }
200 :     wrld->runTime += t0;
201 :    
202 : jhr 1826 FREE(args);
203 :    
204 : jhr 1828 return sched->numSteps;
205 : jhr 1826 }
206 :    

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0