高性能计算并行宇宙:OpenMP 初探
也是 CS149 的准备内容,这次是 OpenMP 的初探。
1 OpenMP Introduction
OpenMP:跨平台、多语言(C、C++、Fortran)
、可扩展的并行计算 API,使得开发者可以轻松利用多核 CPU 的并行计算能力,加速程序的运行。
只需要在编译时加上 -fopenmp 选项即可开启 OpenMP 支持。
在程序中插入 #pragma omp 指令,编译器就会根据指令自动生成多线程代码,例如一个简单例子:
| 1 | printf("Hello, World!\n"); | 
在前面加上一句:
| 1 | 
 | 
程序就会根据硬件情况,在多个线程中执行 printf 语句。
OpenMP 也可以用于循环并行化,例如:
| 1 | 
 | 
2 OpenMP Usage
OpenMP 的指令格式为 #pragma omp parallel [clause[ [, ]clause] ...],其中括号表示可选项,也就是可以有多个子句,每个子句可能有多个参数。下面列一些常见的指令:
- 
#pragma omp parallel:创建一组线程(Team),指示下方 block 代码在每一个线程中并行执行- private(list):指定私有变量
- shared(list):指定共享变量
- default(shared | none):指定默认共享或私有
- num_threads(n):指定线程数
- if(expr):指定条件
- copyin(list):指定复制变量
- sections:配合- #pragma omp section使用
 
- 
#pragma omp for:指示下方 for 循环分配到 Team 中的线程并行执行(每个线程执行一部分,而不是每个线程执行整个循环)
- 
pragma omp single:指示下方 block 代码只在一个线程中执行
- 
#pragma omp simd:指示下方 for 循环可以用 SIMD 优化
- 
#pragma omp section:将不同的 section 分配给不同的线程
- 
#pragma omp parallel for:结合了#pragma omp parallel和#pragma omp for- collapse(n):指定 n 维循环进行并行化
 
- 
#pragma omp critical:指示下方 block 代码只能由一个线程执行
- 
#pragma omp barrier:等待所有线程到达 barrier
- 
#pragma omp master:指示下方 block 代码只在 master 线程中执行
- 
#pragma omp atomic:指示下方语句是原子操作
除了不同的指令之外,OpenMP 还提供了一些库函数,例如:
- omp_get_thread_num():获取当前线程编号
- omp_get_num_threads():获取线程总数
- omp_get_max_threads():获取最大线程数
- omp_get_num_procs():获取处理器数
- omp_set_num_threads(n):设置线程数
以及锁相关的函数:
- omp_init_lock():初始化锁
- omp_destroy_lock():销毁锁
- omp_set_lock():加锁
- omp_unset_lock():解锁
- omp_test_lock():尝试加锁
要了解更多 OpenMP 的用法,可以参考官方文档。
3 OpenMP Example
TODO
References:






