编译命令:
g++ --std=c++17 -Wall -fopenmp -o pi pi.cpp
macOS 自带的 clang++(Apple Clang)默认是不支持 OpenMP的
需要头文件
#include <omp.h>
TODO
// g++ --std=c++17 -Wall -fopenmp -o pi pi.cpp #include <algorithm> #include <iostream> #include <cstdint> #include <chrono> #include <random> #include <cmath> #include <omp.h> const double PI = std::acos(-1.0); inline double monte_carlo( const int32_t num_threads, const int64_t samples_per_thread ) { int64_t total_in_circle = 0, total_samples = num_threads * samples_per_thread; auto start = std::chrono::high_resolution_clock::now(); uint32_t seeds[num_threads]; srand((unsigned)time(nullptr)); for(int32_t i = 0; i < num_threads; i++) { seeds[i] = rand(); } #pragma omp parallel num_threads(num_threads) { std::mt19937 engine; engine.seed(seeds[omp_get_thread_num()]); std::uniform_real_distribution<double> dist(-1.0, 1.0); int64_t in_circle = 0; for (int64_t i = 0; i < samples_per_thread; i++) { double x = dist(engine), y = dist(engine); if (x * x + y * y <= 1.0) { in_circle++; } } #pragma omp atomic total_in_circle += in_circle; } auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration<double> elapsed = end - start; double pi_estimate = 4.0 * total_in_circle / total_samples; double relative_error = std::abs(pi_estimate - PI) / PI; std::cout << "samples=" << total_samples << "(" << num_threads << " threads), pi_estimate=" << pi_estimate << ", rel_error=" << relative_error << ", time=" << elapsed.count() << "s" << std::endl; return pi_estimate; } int main() { monte_carlo(16, 4e8); monte_carlo(32, 2e8); monte_carlo(64, 1e8); monte_carlo(64, 4e8); return 0; }