Created
April 19, 2016 20:01
-
-
Save haileys/db63c008ef87b5f57823c8b210cbc0c9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <pthread.h> | |
#include <errno.h> | |
struct worker_ctx { | |
pthread_t thr; | |
size_t n; | |
size_t stride; | |
size_t offset; | |
size_t result; | |
}; | |
static size_t | |
calc_part(size_t n, size_t stride, size_t offset) | |
{ | |
size_t x, y, c = 0, r = n * n; | |
for (y = offset; y < n; y += stride) { | |
for (x = 0; x < n; x++) { | |
if (x * x + y * y < r) { | |
c++; | |
} | |
} | |
} | |
return c; | |
} | |
static void* | |
thread_main(void* ptr) | |
{ | |
struct worker_ctx* ctx = ptr; | |
ctx->result = calc_part(ctx->n, ctx->stride, ctx->offset); | |
return NULL; | |
} | |
int | |
main(int argc, const char** argv) | |
{ | |
size_t n = 0, w = 0, c = 0, i; | |
if (argc < 3) { | |
fprintf(stderr, "usage: sqpi n worker_count\n"); | |
return 1; | |
} | |
sscanf(argv[1], "%zu", &n); | |
if (n == 0) { | |
fprintf(stderr, "n must > 0\n"); | |
return 1; | |
} | |
sscanf(argv[2], "%zu", &w); | |
if (w == 0) { | |
fprintf(stderr, "worker_count must > 0\n"); | |
return 1; | |
} | |
struct worker_ctx* workers = calloc(n, sizeof(*workers)); | |
if (!workers) { | |
perror("could not allocate workers"); | |
return 1; | |
} | |
for (i = 0; i < w; i++) { | |
workers[i].n = n; | |
workers[i].stride = w; | |
workers[i].offset = i; | |
if (pthread_create(&workers[i].thr, NULL, thread_main, &workers[i])) { | |
perror("could not spawn worker thread"); | |
return 1; | |
} | |
} | |
for (i = 0; i < w; i++) { | |
if (pthread_join(workers[i].thr, NULL)) { | |
perror("could not join worker thread"); | |
return 1; | |
} | |
} | |
for (i = 0; i < n; i++) { | |
c += workers[i].result; | |
} | |
double result = ((double)c / (double)(n * n)) * 4.0; | |
printf("%lf\n", result); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment