/* * C program to compute the value of pi using Monte Carlo method. * * command-line arguments: number_of_samples, seed * * Preliminary OpenMP parallel version. Does not work well -- results * are the same as sequential version, but performance is no better * (for reasons as discussed in class). */ #include #include #include /* has fabs() */ /* copied from not-strictly-standard part of math.h */ #define M_PI 3.14159265358979323846 #include #include "timer.h" /* has get_time() */ /* main program */ int main(int argc, char* argv[]) { char* usage_fmt = "usage: %s number_of_samples seed\n"; char* end_ptr_for_strtol; /* process command-line arguments */ if (argc != 3) { fprintf(stderr, usage_fmt, argv[0]); exit(EXIT_FAILURE); } long num_samples = strtol(argv[1], &end_ptr_for_strtol, 10); if (*end_ptr_for_strtol != '\0') { fprintf(stderr, usage_fmt, argv[0]); exit(EXIT_FAILURE); } long seed = strtol(argv[2], &end_ptr_for_strtol, 10); if (*end_ptr_for_strtol != '\0') { fprintf(stderr, usage_fmt, argv[0]); exit(EXIT_FAILURE); } int nthreads; /* record start time */ double start_time = get_time(); /* do calculation */ srand((unsigned int) seed); long count = 0; double x, y; #pragma omp parallel { #pragma omp master { nthreads = omp_get_num_threads(); } #pragma omp for private(x,y) reduction(+:count) schedule(static) for (long i = 0; i < num_samples; ++i) { /* apparently rand() is not thread-safe */ x = (double) rand() / (double) (RAND_MAX); y = (double) rand() / (double) (RAND_MAX); if ((x*x + y*y) <= 1.0) ++count; } } double pi = 4.0 * (double) count / (double) num_samples; /* record end time and print results */ double end_time = get_time(); printf("OpenMP C program results with %d threads:\n", nthreads); printf("number of samples = %ld, seed = %ld\n", num_samples, seed); printf("estimated pi = %12.10f\n", pi); printf("difference between estimated pi and math.h M_PI = %12.10f\n", fabs(pi - M_PI)); printf("time to compute = %g seconds\n", end_time - start_time); /* clean up and return */ return EXIT_SUCCESS; }