LLVM OpenMP 19.0.0git
omp_for_schedule_guided.c
Go to the documentation of this file.
1// RUN: %libomp-compile-and-run
2
3/* Test for guided scheduling
4 * Ensure threads get chunks interleavely first
5 * Then judge the chunk sizes are decreasing to a stable value
6 * Modified by Chunhua Liao
7 * For example, 100 iteration on 2 threads, chunksize 7
8 * one line for each dispatch, 0/1 means thread id
9 * 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24
10 * 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 18
11 * 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14
12 * 1 1 1 1 1 1 1 1 1 1 10
13 * 0 0 0 0 0 0 0 0 8
14 * 1 1 1 1 1 1 1 7
15 * 0 0 0 0 0 0 0 7
16 * 1 1 1 1 1 1 1 7
17 * 0 0 0 0 0 5
18*/
19#include <stdio.h>
20#include <stdlib.h>
21#include "omp_testsuite.h"
22#include "omp_my_sleep.h"
23
24#define CFSMAX_SIZE 1000
25#define MAX_TIME 0.005
26
27#ifdef SLEEPTIME
28#undef SLEEPTIME
29#define SLEEPTIME 0.0001
30#endif
31
33{
34 int * tids;
35 int * chunksizes;
36 int notout;
37 int maxiter;
38 int threads;
39 int i;
40 int result;
41
42 tids = (int *) malloc (sizeof (int) * (CFSMAX_SIZE + 1));
43 maxiter = 0;
44 result = 1;
45 notout = 1;
46
47 /* Testing if enough threads are available for this check. */
48 #pragma omp parallel
49 {
50 #pragma omp single
51 {
52 threads = omp_get_num_threads();
53 }
54 }
55
56 /* ensure there are at least two threads */
57 if (threads < 2) {
59 threads = 2;
60 }
61
62 /* Now the real parallel work:
63 * Each thread will start immediately with the first chunk.
64 */
65 #pragma omp parallel shared(tids,maxiter)
66 { /* begin of parallel */
67 double count;
68 int tid;
69 int j;
70
71 tid = omp_get_thread_num ();
72
73 #pragma omp for nowait schedule(guided)
74 for(j = 0; j < CFSMAX_SIZE; ++j) {
75 count = 0.;
76 #pragma omp flush(maxiter)
77 if (j > maxiter) {
78 #pragma omp critical
79 {
80 maxiter = j;
81 }
82 }
83 /*printf ("thread %d sleeping\n", tid);*/
84 #pragma omp flush(maxiter,notout)
85 while (notout && (count < MAX_TIME) && (maxiter == j)) {
86 #pragma omp flush(maxiter,notout)
89#ifdef VERBOSE
90 printf(".");
91#endif
92 }
93#ifdef VERBOSE
94 if (count > 0.) printf(" waited %lf s\n", count);
95#endif
96 /*printf ("thread %d awake\n", tid);*/
97 tids[j] = tid;
98#ifdef VERBOSE
99 printf("%d finished by %d\n",j,tid);
100#endif
101 } /* end of for */
102 notout = 0;
103 #pragma omp flush(maxiter,notout)
104 } /* end of parallel */
105
106 /*******************************************************
107 * evaluation of the values *
108 *******************************************************/
109 {
110 int determined_chunksize = 1;
111 int last_threadnr = tids[0];
112 int global_chunknr = 0;
113 int openwork = CFSMAX_SIZE;
114 int expected_chunk_size;
115 int* local_chunknr = (int*)malloc(threads * sizeof(int));
116 double c = 1;
117
118 for (i = 0; i < threads; i++)
119 local_chunknr[i] = 0;
120
121 tids[CFSMAX_SIZE] = -1;
122
123 /*
124 * determine the number of global chunks
125 */
126 // fprintf(stderr,"# global_chunknr thread local_chunknr chunksize\n");
127 for(i = 1; i <= CFSMAX_SIZE; ++i) {
128 if (last_threadnr==tids[i]) {
129 determined_chunksize++;
130 } else {
131 /* fprintf(stderr, "%d\t%d\t%d\t%d\n", global_chunknr,
132 last_threadnr, local_chunknr[last_threadnr], m); */
133 global_chunknr++;
134 local_chunknr[last_threadnr]++;
135 last_threadnr = tids[i];
136 determined_chunksize = 1;
137 }
138 }
139 /* now allocate the memory for saving the sizes of the global chunks */
140 chunksizes = (int*)malloc(global_chunknr * sizeof(int));
141
142 /*
143 * Evaluate the sizes of the global chunks
144 */
145 global_chunknr = 0;
146 determined_chunksize = 1;
147 last_threadnr = tids[0];
148 for (i = 1; i <= CFSMAX_SIZE; ++i) {
149 /* If the threadnumber was the same as before increase the
150 * detected chunksize for this chunk otherwise set the detected
151 * chunksize again to one and save the number of the next
152 * thread in last_threadnr.
153 */
154 if (last_threadnr == tids[i]) {
155 determined_chunksize++;
156 } else {
157 chunksizes[global_chunknr] = determined_chunksize;
158 global_chunknr++;
159 local_chunknr[last_threadnr]++;
160 last_threadnr = tids[i];
161 determined_chunksize = 1;
162 }
163 }
164
165#ifdef VERBOSE
166 fprintf(stderr, "found\texpected\tconstant\n");
167#endif
168
169 /* identify the constant c for the exponential
170 decrease of the chunksize */
171 expected_chunk_size = openwork / threads;
172 c = (double) chunksizes[0] / expected_chunk_size;
173
174 for (i = 0; i < global_chunknr; i++) {
175 /* calculate the new expected chunksize */
176 if (expected_chunk_size > 1)
177 expected_chunk_size = c * openwork / threads;
178#ifdef VERBOSE
179 fprintf(stderr, "%8d\t%8d\t%lf\n", chunksizes[i],
180 expected_chunk_size, c * chunksizes[i]/expected_chunk_size);
181#endif
182 /* check if chunksize is inside the rounding errors */
183 if (abs (chunksizes[i] - expected_chunk_size) >= 2) {
184 result = 0;
185#ifndef VERBOSE
186 fprintf(stderr, "Chunksize differed from expected "
187 "value: %d instead of %d\n", chunksizes[i],
188 expected_chunk_size);
189 return 0;
190#endif
191 } /* end if */
192
193#ifndef VERBOSE
194 if (expected_chunk_size - chunksizes[i] < 0)
195 fprintf(stderr, "Chunksize did not decrease: %d"
196 " instead of %d\n", chunksizes[i],expected_chunk_size);
197#endif
198
199 /* calculating the remaining amount of work */
200 openwork -= chunksizes[i];
201 }
202 }
203 return result;
204}
205
206int main()
207{
208 int i;
209 int num_failed=0;
210
211 for(i = 0; i < REPETITIONS; i++) {
213 num_failed++;
214 }
215 }
216 return num_failed;
217}
int result[2]
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t count
KMP_ARCH_X86 KMP_ARCH_X86 long double
#define i
Definition: kmp_stub.cpp:87
#define omp_set_num_threads
Definition: kmp_stub.cpp:34
#define CFSMAX_SIZE
#define MAX_TIME
int test_omp_for_schedule_guided()
int main()
static void my_sleep(double sleeptime)
Utility function to have a sleep function with better resolution and which only stops one thread.
Definition: omp_my_sleep.h:24
#define SLEEPTIME
Definition: omp_testsuite.h:16
#define REPETITIONS
Definition: omp_testsuite.h:13
int omp_get_num_threads()