Untitled
user_4058768
plain_text
13 days ago
3.9 kB
3
Indexable
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <time.h> #include <math.h> // Structure to pass arguments to threads typedef struct { long long points_per_thread; long long points_in_circle; unsigned int seed; } ThreadData; // Thread function to generate random points and count those in the circle void* monte_carlo_task(void* arg) { ThreadData* data = (ThreadData*)arg; long long local_count = 0; double x, y; // Each thread uses a different seed to avoid correlation unsigned int local_seed = data->seed; for (long long i = 0; i < data->points_per_thread; i++) { // Generate random points between -1 and 1 x = (double)rand_r(&local_seed) / RAND_MAX * 2 - 1; y = (double)rand_r(&local_seed) / RAND_MAX * 2 - 1; // Check if point is inside circle if (x*x + y*y <= 1) local_count++; } // Store result in the structure data->points_in_circle = local_count; return NULL; } int main(int argc, char* argv[]) { long long total_points = 100000000; // 100 million points by default int num_threads = 4; // Default number of threads double pi_estimate, pi_error; double execution_time; long long total_in_circle = 0; // Check if number of threads is provided as command line argument if (argc > 1) { num_threads = atoi(argv[1]); if (num_threads <= 0) { printf("Number of threads must be positive, using default (4)\n"); num_threads = 4; } } // Optional: Allow specifying number of points via command line if (argc > 2) { total_points = atoll(argv[2]); if (total_points <= 0) { printf("Number of points must be positive, using default (100M)\n"); total_points = 100000000; } } printf("Running Monte Carlo Pi estimation with %d threads and %lld points\n", num_threads, total_points); // Allocate thread and data arrays pthread_t* threads = (pthread_t*)malloc(num_threads * sizeof(pthread_t)); ThreadData* thread_data = (ThreadData*)malloc(num_threads * sizeof(ThreadData)); if (!threads || !thread_data) { perror("Failed to allocate memory"); return 1; } // Calculate points per thread (handle remainder) long long points_per_thread = total_points / num_threads; long long remainder = total_points % num_threads; // Start timing struct timespec start_time, end_time; clock_gettime(CLOCK_MONOTONIC, &start_time); // Create threads for (int i = 0; i < num_threads; i++) { thread_data[i].points_per_thread = points_per_thread + (i < remainder ? 1 : 0); thread_data[i].points_in_circle = 0; thread_data[i].seed = time(NULL) + i; // Different seed for each thread if (pthread_create(&threads[i], NULL, monte_carlo_task, &thread_data[i]) != 0) { perror("Failed to create thread"); return 1; } } // Wait for all threads to complete for (int i = 0; i < num_threads; i++) { if (pthread_join(threads[i], NULL) != 0) { perror("Failed to join thread"); return 1; } total_in_circle += thread_data[i].points_in_circle; } // Stop timing clock_gettime(CLOCK_MONOTONIC, &end_time); // Calculate pi and execution time pi_estimate = 4.0 * total_in_circle / total_points; execution_time = (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec - start_time.tv_nsec) / 1e9; pi_error = fabs((pi_estimate - M_PI) / M_PI * 100); // Print results printf("Estimated Pi: %.10f\n", pi_estimate); printf("Actual Pi: %.10f\n", M_PI); printf("Error: %.10f%%\n", pi_error); printf("Execution time: %.6f seconds\n", execution_time); // Free allocated memory free(threads); free(thread_data); return 0; }
Editor is loading...
Leave a Comment