Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * coding: utf-8
- *
- * Copyright (C) 2013, Niklas Rosenstein
- * All rights reserved.
- *
- * Licensed under the GNU General Public License.
- */
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #include <math.h>
- #include <time.h>
- #include <pthread.h>
- #define TRUE (1)
- #define FALSE (0)
- enum EXITCODE {
- EXITCODE_OK = 0,
- EXITCODE_INVALIDARGUMENTS,
- EXITCODE_UNKOWNARGUMENTS,
- EXITCODE_FAILURE,
- EXITCODE_MEMORY,
- };
- enum ARGTYPE {
- ARGTYPE_INT,
- ARGTYPE_BOOL,
- ARGTYPE_STRING,
- ARGTYPE_GIVEN,
- };
- enum PARSERESULT {
- PARSERESULT_OK = 0,
- PARSERESULT_NOTOK,
- PARSERESULT_MISSINGARGUMENT,
- PARSERESULT_WRONGARGUMENT,
- PARSERESULT_WRONGARGTYPE,
- PARSERESULT_NOTSUPPORTED,
- };
- typedef enum ARGTYPE ARGTYPE;
- typedef enum PARSERESULT PARSERESULT;
- int str_is_int(char* string) {
- if (*string == '+' || *string == '-') string++;
- while (*string != 0) {
- if (*string < '0' || *string > '9') return FALSE;
- string++;
- }
- return TRUE;
- }
- char* g_matched = NULL;
- PARSERESULT check_arg(int argc, char** argv, int* i, char* argname,
- void* dest, ARGTYPE type) {
- if (strcmp(argv[*i], argname) == 0) {
- if (*i + 1 >= argc && type != ARGTYPE_GIVEN) {
- printf("Missing value for argument %s\n", argname);
- exit(EXIT_FAILURE);
- return PARSERESULT_MISSINGARGUMENT;
- }
- }
- else {
- return PARSERESULT_NOTOK;
- }
- if (g_matched) g_matched[*i] = TRUE;
- if (!dest) return PARSERESULT_OK;
- int increment = TRUE;
- char* value = argv[*i + 1];
- PARSERESULT result = PARSERESULT_OK;
- switch (type) {
- case ARGTYPE_INT:
- if (!str_is_int(value)) {
- printf("Integer value expected for argument %s.\n", argname);
- return PARSERESULT_WRONGARGUMENT;
- }
- *(int*) dest = atoi(value);
- break;
- case ARGTYPE_BOOL:
- result = PARSERESULT_NOTSUPPORTED;
- break;
- case ARGTYPE_STRING:
- result = PARSERESULT_NOTSUPPORTED;
- break;
- case ARGTYPE_GIVEN:
- increment = FALSE;
- *(char*) dest = TRUE;
- break;
- default:
- return PARSERESULT_WRONGARGTYPE;
- }
- if (increment) (*i)++;
- if (g_matched) g_matched[*i] = TRUE;
- return result;
- }
- int alloc_failed() {
- printf("Memory error, allocation failed.\n");
- return EXITCODE_MEMORY;
- }
- double rand_01() {
- return (double) rand() / (double) RAND_MAX;
- }
- double pi_mc(int iterations) {
- long long inner = 0;
- long long outer = 0;
- int i;
- for (i=0; i < iterations; i++) {
- double x = rand_01();
- double y = rand_01();
- double d = sqrt(pow(x, 2.0) + pow(y, 2.0));
- if (d <= 1.0) {
- inner++;
- }
- else {
- outer++;
- }
- }
- return ((double) inner / (double) iterations) * 4;
- }
- struct PIThreadData {
- int iterations;
- double out;
- };
- void* pi_mc_threaded(void* ptr) {
- struct PIThreadData* data = ptr;
- data->out = pi_mc(data->iterations);
- }
- int main(int argc, char** argv) {
- int i;
- // Arguments structure.
- struct {
- char stats;
- char colored;
- int iterations;
- int threads;
- } args = {0};
- args.iterations = (int) pow(10, 6);
- args.threads = 1;
- // Parse command-line arguments.
- int pos_arg = 0;
- g_matched = calloc(argc, 1);
- if (!g_matched) {
- return alloc_failed();
- }
- for (i=1; i < argc; i++) {
- check_arg(argc, argv, &i, "-iterations", &args.iterations, ARGTYPE_INT);
- check_arg(argc, argv, &i, "-threads", &args.threads, ARGTYPE_INT);
- check_arg(argc, argv, &i, "-stats", &args.stats, ARGTYPE_GIVEN);
- check_arg(argc, argv, &i, "-colored", &args.colored, ARGTYPE_GIVEN);
- }
- // Print out not-matched arguments.
- for (i=1; i < argc; i++) {
- if (g_matched[i] == 0) {
- printf("Unkown argument %d: %s\n", i, argv[i]);
- return EXITCODE_UNKOWNARGUMENTS;
- }
- }
- free(g_matched);
- g_matched = NULL;
- // Validate arguments.
- if (args.iterations < 1) {
- printf("Argument -iterations must be an integer greater than zero.\n");
- return EXITCODE_INVALIDARGUMENTS;
- }
- if (args.threads < 1) {
- printf("Argument -threads must be an integer greater than zero.\n");
- return EXITCODE_INVALIDARGUMENTS;
- }
- // Begin computation.
- clock_t t_start, t_delta;
- double pi = 0;
- if (args.threads == 1) {
- t_start = clock();
- pi = pi_mc(args.iterations);
- t_delta = clock() - t_start;
- }
- else {
- pthread_t* threads = malloc(sizeof(pthread_t) * args.threads);
- if (!threads) {
- return alloc_failed();
- }
- struct PIThreadData* values = malloc(sizeof(struct PIThreadData) * args.threads);
- if (!values) {
- free(threads);
- return alloc_failed();
- }
- t_start = clock();
- for (i=0; i < args.threads; i++) {
- values[i].iterations = args.iterations;
- values[i].out = 0.0;
- pthread_create(threads + i, NULL, pi_mc_threaded, values + i);
- }
- for (i=0; i < args.threads; i++) {
- pthread_join(threads[i], NULL);
- pi += values[i].out;
- }
- t_delta = clock() - t_start;
- free(threads);
- threads = NULL;
- free(values);
- values = NULL;
- pi /= (double) args.threads;
- }
- if (args.colored) {
- printf("\033[33m%f\033[0m\n", pi);
- }
- else {
- printf("%f\n", pi);
- }
- // Show stats if desired.
- if (args.stats) {
- printf("\n");
- printf("Number of iterations: %d\n", args.iterations * args.threads);
- printf("Method: Monte Carlo\n");
- printf("Evaluation time: %f sec\n", ((double) t_delta) / CLOCKS_PER_SEC);
- printf("Threads: ");
- if (args.threads == 1) printf("Main\n");
- else printf("%d\n", args.threads);
- }
- return EXITCODE_OK;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement