高性能计算并行宇宙: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: