/* * Generic example of master/worker program. "Tasks" just consist of sleeping * for a specified time; times to wait are generatedly randomly from 0 to a * specified maximum. * * Command-line arguments: total tasks, maximum task time, * (optional) "--verbose" for verbose output * * Parallel version using OpenMP and static assignment of tasks to workers. */ #include #include #include #include /* a short function to print a message and exit */ void error_exit(char msg[]) { fprintf(stderr, "%s", msg); exit(EXIT_FAILURE); } /* function to generate a random integer in [start, end] */ int random_in_range(int start, int end) { /* use method described in "rand" man page */ return start + ((double) (end-start+1) * rand()/(RAND_MAX + 1.0)); } /* ---- main program ---- */ int main(int argc, char *argv[]) { int num_tasks; int max_task_time; double start_time, end_time; int i; int task_time; int total_task_time = 0; int max_thread_total_task_time; int min_thread_total_task_time; int verbose = 0; int nthreads; if (argc < 3) { error_exit("usage: master-worker num_tasks max_task_time [--verbose]\n"); } num_tasks = atoi(argv[1]); max_task_time = atoi(argv[2]); if (argc > 3) verbose = 1; max_thread_total_task_time = 0; min_thread_total_task_time = max_task_time * num_tasks; start_time = omp_get_wtime(); #pragma omp parallel private(task_time) { int thread_total_task_time = 0; int thread_num_tasks = 0; int thread_ID = omp_get_thread_num(); #pragma omp single { nthreads = omp_get_num_threads(); } #pragma omp for schedule(static) for (i = 0; i < num_tasks; ++i) { #pragma omp critical { task_time = random_in_range(1, max_task_time); } thread_total_task_time += task_time; ++thread_num_tasks; if (verbose) printf("(thread %d) task time = %d\n", thread_ID, task_time); usleep(task_time * 1000); } printf("thread %d number of tasks = %d, total time = %d\n", thread_ID, thread_num_tasks, thread_total_task_time); #pragma omp critical { if (thread_total_task_time > max_thread_total_task_time) max_thread_total_task_time = thread_total_task_time; if (thread_total_task_time < min_thread_total_task_time) min_thread_total_task_time = thread_total_task_time; total_task_time += thread_total_task_time; } } end_time = omp_get_wtime(); printf("\nOpenMP parallel version with %d threads\n", nthreads); printf("number of tasks = %d\n", num_tasks); printf("max task time = %d\n", max_task_time); printf("total task time = %d\n", total_task_time); printf("total task time in threads ranges from %d to %d\n", min_thread_total_task_time, max_thread_total_task_time); printf("running time = %g\n", end_time - start_time); return EXIT_SUCCESS; }