cpp11/pi.cc

59 lines
1.3 KiB
C++

#include <iostream>
#include <thread>
#include <atomic>
#include <sys/time.h>
#include <ctime>
#include <cmath>
#include <random>
static const int num_threads = 8;
static const int max_ = 100000;
void slice_of_pi(int tries, int my_id, std::atomic<int> & in_circle) {
struct timeval tv;
gettimeofday(&tv, NULL);
srand(tv.tv_usec + my_id);
std::uniform_int_distribution<int> distribution {0, max_};
std::mt19937 engine; // Mersenne twister MT19937
auto generator = std::bind(distribution, engine);
double x, y, d;
int _in_circle = 0;
for(int i = 0; i < tries; i++) {
x = (float)generator() / (float)max_;
y = (float)generator() / (float)max_;
d = sqrt(x * x + y * y);
if(d < 1.0)
_in_circle++;
}
in_circle += _in_circle;
}
int main(int argc, char * argv[]) {
if(argc != 2) {
std::cerr << "pi <number of attempts>" << std::endl;
return 1;
}
std::atomic<int> successes {0};
int attempts = atoi(argv[1]);
std::thread t[num_threads];
for (int i = 0; i < num_threads; ++i) {
t[i] = std::thread(slice_of_pi, attempts, i, std::ref(successes));
}
for (int i = 0; i < num_threads; ++i) {
t[i].join();
}
float pi = 4 * float(successes) / float(attempts * num_threads);
printf("%0.8f\n", pi);
return 0;
}