Zhonghui

每个不曾起舞的日子,都是对生命的辜负

User Tools

Site Tools


程序:openmp:openmp

Table of Contents

OpenMP

  1. OpenMP 是一种基于指令(#pragma)的多线程编程标准。
  2. 适用于 共享内存 架构。
  3. 主要支持 C/C++ 和 FORTRAN。
  4. 编译器根据指令自动插入并行化代码,支持逐步并行化与调试。

编译命令:

g++ --std=c++17 -Wall -fopenmp -o pi pi.cpp

macOS 自带的 clang++(Apple Clang)默认是不支持 OpenMP的

需要头文件

#include <omp.h>

指令总结

TODO

sample code

// 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;
}
/var/www/DokuWikiStick/dokuwiki/data/pages/程序/openmp/openmp.txt · Last modified: 2025/07/18 13:37 by zhonghui