OpenMP是一个多线程程序的框架,使用OpenMP,可以轻松实现多线程加速计算。
Created 2022.02.22 by William Yu; Last modified: 2022.02.22-v1.0.1
Contact: windmillyucong@163.com
Copyleft! 2022 William Yu. Some rights reserved.
OpenMP
References
- https://www.openmp.org/wp-content/uploads/omp-hands-on-SC08.pdf
- https://www.cnblogs.com/wxquare/p/5584662.html
1. OpenMP简介
OpenMP (Open Multi-Processing) 是一个支持跨平台共享内存多线程并发的API,使用C、C++和Fortran语言。它由一组编译器指令、库例程和环境变量组成,这些共同定义了并行执行的规则。
1.1 主要特点
- 简单易用:只需添加编译指令即可实现并行
- 可移植性:支持多种平台和编译器
- 可扩展性:支持从单核到多核的扩展
- 灵活性:支持增量并行化
2. 基本用法
2.1 编译和链接
使用gcc/g++编译时,需要添加-fopenmp
选项:
1
g++ -fopenmp program.cpp -o program
2.2 基本指令
最常用的OpenMP指令包括:
1
2
3
4
5
#pragma omp parallel // 创建并行区域
#pragma omp for // 并行化for循环
#pragma omp sections // 并行化代码段
#pragma omp critical // 临界区
#pragma omp atomic // 原子操作
2.3 环境变量
常用的环境变量:
1
2
export OMP_NUM_THREADS=4 # 设置线程数
export OMP_SCHEDULE="dynamic" # 设置调度策略
3. 示例代码
3.1 基本并行区域
1
2
3
4
5
6
7
8
9
10
11
#include <omp.h>
#include <iostream>
int main() {
#pragma omp parallel
{
int thread_id = omp_get_thread_num();
std::cout << "Hello from thread " << thread_id << std::endl;
}
return 0;
}
3.2 并行化for循环
将要进行多线程处理的for循环一定是独立的(independent)
1
2
3
4
5
6
7
8
9
10
11
12
#include <omp.h>
#include <vector>
int main() {
std::vector<int> data(1000);
#pragma omp parallel for
for(int i = 0; i < 1000; i++) {
data[i] = i * i;
}
return 0;
}
3.3 使用reduction
1
2
3
4
5
6
7
8
9
10
11
#include <omp.h>
int main() {
int sum = 0;
#pragma omp parallel for reduction(+:sum)
for(int i = 0; i < 1000; i++) {
sum += i;
}
return 0;
}
4. 性能优化建议
- 避免在并行区域中创建和销毁线程
- 合理设置线程数量
- 注意数据竞争和同步开销
- 使用适当的调度策略
- 避免false sharing
5. 常见问题
5.1 数据竞争
当多个线程同时访问共享数据时可能发生数据竞争。使用以下方法避免:
- 使用critical区域
- 使用atomic操作
- 使用private子句
- 使用reduction子句
5.2 负载均衡
使用不同的调度策略来优化负载均衡:
- static:静态分配
- dynamic:动态分配
- guided:引导式分配
- auto:由系统决定
Contact
Feel free to contact me windmillyucong@163.com anytime for anything.