Made it run continuously
This commit is contained in:
parent
d8cfccf898
commit
6076e7c94f
@ -9,53 +9,76 @@
|
||||
#include <thread>
|
||||
#include <random>
|
||||
#include <chrono>
|
||||
#include <iomanip>
|
||||
|
||||
void compute(std::atomic<long long> &inside, long long iterations){
|
||||
long long to_add = 0;
|
||||
struct stats {
|
||||
std::atomic<long long> iterations;
|
||||
std::atomic<long long> points_inside;
|
||||
std::chrono::time_point<std::chrono::steady_clock> start_time;
|
||||
|
||||
stats(std::chrono::time_point<std::chrono::steady_clock> start){
|
||||
iterations = 0;
|
||||
points_inside = 0;
|
||||
start_time = start;
|
||||
}
|
||||
};
|
||||
|
||||
void compute(std::atomic<long long> &inside, std::atomic<long long> &iterations){
|
||||
unsigned int seed = (unsigned int) std::chrono::system_clock::now().time_since_epoch().count();
|
||||
std::mt19937 e2(seed);
|
||||
std::uniform_real_distribution<double> dis(0.0, 1.0);
|
||||
for(int i=0; i<iterations; i++){
|
||||
double x = dis(e2);
|
||||
double y = dis(e2);
|
||||
if(x*x+y*y<=1){
|
||||
to_add++;
|
||||
while(1){
|
||||
long long add_inside = 0;
|
||||
for(int i=0; i<250000; i++){
|
||||
double x = dis(e2);
|
||||
double y = dis(e2);
|
||||
if(x*x+y*y<1){
|
||||
add_inside++;
|
||||
}
|
||||
}
|
||||
inside+=add_inside;
|
||||
iterations+=250000;
|
||||
|
||||
}
|
||||
inside+=to_add;
|
||||
}
|
||||
|
||||
double monte_carlo(long long iterations){
|
||||
|
||||
std::atomic<long long> inside(0);
|
||||
void monte_carlo(stats &stats){
|
||||
|
||||
std::vector<std::thread> threads;
|
||||
|
||||
int threadcount = std::thread::hardware_concurrency();;
|
||||
|
||||
long long actual_n = iterations - iterations % threadcount;
|
||||
|
||||
for(int i=0; i<threadcount; i++){
|
||||
threads.emplace_back(compute, std::ref(inside), iterations/threadcount);
|
||||
threads.emplace_back(compute, std::ref(stats.points_inside), std::ref(stats.iterations));
|
||||
}
|
||||
|
||||
|
||||
|
||||
for(auto& t : threads){
|
||||
t.join();
|
||||
}
|
||||
}
|
||||
|
||||
return inside * 4 / (double)actual_n;
|
||||
void report_stats(stats &full_stats){
|
||||
using namespace std::chrono_literals;
|
||||
double pi = 4*(double)full_stats.points_inside/(double)full_stats.iterations;
|
||||
auto time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now()-full_stats.start_time);
|
||||
|
||||
double iterations_per_second = full_stats.iterations / time_ms.count() * 1000;
|
||||
|
||||
std::cout << "ran for "<<time_ms <<"\n";
|
||||
std::cout << "iterations: "<<full_stats.iterations << "\ninside: "<< full_stats.points_inside <<std::fixed<< std::setprecision(10)<< "\npi: "<<pi<<"\n";
|
||||
std::cout << "speed: "<<std::scientific<<std::setprecision(2)<<iterations_per_second<<"/s\n";
|
||||
std::this_thread::sleep_for(1000ms);
|
||||
report_stats(std::ref(full_stats));
|
||||
}
|
||||
|
||||
int main() {
|
||||
// testing with 1,000,000,000 iterations for now
|
||||
std::vector<double> pi_values;
|
||||
double pi_average = 0;
|
||||
for(int i=0; i<10; i++){
|
||||
double pi = monte_carlo(1e9);
|
||||
std::cout << "Computed pi #"<<i+1<<" result: "<<pi << "\n";
|
||||
pi_values.push_back(pi);
|
||||
pi_average+=pi/10;
|
||||
}
|
||||
std::cout << "iterations: "<<1e8<<", pi: "<<pi_average<<','<<"\n";
|
||||
return 0;
|
||||
|
||||
stats full_stats(std::chrono::steady_clock::now());
|
||||
|
||||
std::thread rst(report_stats, std::ref(full_stats));
|
||||
monte_carlo(full_stats);
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user