网站设计要点,wordpress 图片裁剪,app网站开发,网站设置密码访问#x1f9e0; 什么是 OpenMP#xff1f;
OpenMP#xff08;Open Multi-Processing#xff09; 是一种基于 共享内存多线程并行编程 的标准接口#xff0c;主要用于 C/C 和 Fortran。 它通过编译器指令#xff08;#pragma#xff09;和少量函数调用#xff0c;实现程序… 什么是 OpenMP
OpenMPOpen Multi-Processing 是一种基于 共享内存多线程并行编程 的标准接口主要用于 C/C 和 Fortran。 它通过编译器指令#pragma和少量函数调用实现程序的多线程并行执行广泛用于多核 CPU 的并行加速。 ✅ 关键词简单、快速接入、共享内存模型、线程级并行 基本原理 OpenMP 利用多线程模型多个线程访问同一块共享内存。 主线程启动并分配工作到多个子线程。 子线程完成任务后回收继续主线程的流程。 使用步骤C 示例
1. 头文件引入
#include omp.h2. 编译器支持
使用 -fopenmpGCC/Clang 或 /openmpMSVC
g -fopenmp main.cpp -o my_app常用指令详解
1. 并行执行块
#pragma omp parallel
{// 这里的代码由多个线程并行执行
}2. 并行 for 循环
#pragma omp parallel for
for (int i 0; i N; i) {// 多线程并行执行每一次迭代
}3. 指定共享与私有变量
#pragma omp parallel for shared(shared_var) private(i)shared(x)所有线程共享变量 private(x)每个线程有自己的副本
4. critical临界区
保证某段代码只被一个线程执行
#pragma omp critical
{// 通常用于修改共享变量如 push_back、计数等
}5. reduction规约
并行执行中对变量进行“聚合”
int sum 0;
#pragma omp parallel for reduction(:sum)
for (int i 0; i N; i)sum i; // 各线程加和后统一聚合6. atomic原子操作
原子性地更新变量比 critical 粒度更小
#pragma omp atomic
sum i;7. schedule任务划分策略
控制任务在线程间如何分配
#pragma omp parallel for schedule(static) // 固定分配
#pragma omp parallel for schedule(dynamic) // 动态分配运行时函数
int omp_get_num_threads(); // 获取当前线程数
int omp_get_thread_num(); // 获取当前线程 ID从 0 开始
int omp_get_max_threads(); // 系统支持的最大线程数示例并行求数组和
#include omp.h
#include iostream
int main() {const int N 1000;int a[N];for (int i 0; i N; i) a[i] i;long long sum 0;#pragma omp parallel for reduction(:sum)for (int i 0; i N; i) {sum a[i];}std::cout Sum sum std::endl;return 0;
}⚠️ 使用注意事项
问题描述❌ 数据竞争多线程读写同一变量未加锁或同步可能崩溃❌ 非线程安全容器std::vector、deque 等 STL 容器需手动保护❌ 非结构化编程不当的 #pragma 结构容易导致 bug❌ 嵌套并行默认为关闭需手动打开 omp_set_nested(1) ✅ 适合的使用场景
场景说明CPU 密集型计算大量循环计算、矩阵乘法、图像处理数据并行处理同一类型的大量数据图像 Patch 并行处理图像分块 #pragma omp parallel for替代多线程简洁替代 pthread/C std::thread 等 优缺点总结
优点缺点✅ 易上手❌ 仅支持共享内存系统✅ 与现有代码融合简单❌ 控制粒度较粗不适合复杂任务分配✅ 开销小无需线程池❌ 对线程安全性要求高容易出错 补充工具 GOMPGNU OpenMP Runtime你遇到的 libgomp.so 就是它OpenMP 的运行时。 Intel TBB / C20 并行算法适合更复杂的并行场景。 OpenCL / CUDA适合跨设备GPU并行。 执行例子 #include iostream
#include omp.hint main() {#pragma omp parallel{int tid omp_get_thread_num();std::cout Thread %d says hello\n tid std::endl;int num_threads omp_get_num_threads();std::cout Number of threads: num_threads std::endl;}std::cout ------------------------- std::endl;#pragma omp parallel forfor (int i 0; i 8; i) {printf(Thread %d handles i %d\n, omp_get_thread_num(), i);int tid omp_get_thread_num();std::cout the threads is: tid std::endl;std::cout std::endl;}std::cout ------------------------- std::endl;int public_val 0;for(int i0; i10; i){public_val 1;}std::cout the public_val is: public_val std::endl;public_val 0;#pragma omp parallel forfor(int i0; i10; i){ #pragma omp criticalpublic_val 1;}std::cout the public_val is: public_val std::endl;public_val 0;#pragma omp parallel forfor(int i0; i10; i){ public_val 1;}std::cout the public_val is: public_val std::endl;return 0;
}// g main.cpp -fopenmp -o hello