OpenMP
OpenMP是CPU的并行编程模型,它使用编译器指令来识别并行区域。
omp_set_num_threads(n_streams);//用来指定要用到的CPU线程数,类似于设置环境变量
#pragma omp parrallel //标记代码为并行部分
{
int i= omp_get_thread_num();//为每个主机线程返回唯一的线程ID,将该ID作为streams数组的索引,实现OpenMP线程与CUDA流的一一对应
kernel_1<<<gria,block,0,streams[i]>>>();
kernel_2<<<gria,block,0,streams[i]>>>();
kernel_3<<<gria,block,0,streams[i]>>>();
kernel_4<<<gria,block,0,streams[i]>>>();
}
//下面是上述代码更简单可靠的OpenMP指令形式
#pragma omp parrallel num_threads(n)//指定OpenMP并行区域里要用到的CPU线程数
{
int i= omp_get_thread_num();//为每个主机线程返回唯一的线程ID
}
在OpenMP并行区域之前或之后进行分配/释放资源能够在该区域达到最佳的CPU利用率。
编译命令
$ nvcc -O3 -Xcomplier -fopenmp src.cu -o dst -lgomp
OpenACC
OpenACC是OpenMP模型在GPU上的扩展,两者极其相似。
OpenAcc是CUDA的一个补充编程模型,使用基于编译器指令的API,具有高性能、可编程性和跨平台可移植性。OpenACC由Nvidia主攻编译器的子公司PGI提出并开源,它们的编译器为pgcc。
OpenACC 规范要求支持它的编译器预定义一个宏_OPENACC
,宏的值为 yyyymm ,其中 yyyy 是编译器所支持 OpenACC 版本的发布年份, mm 是月份。
编程模型
OpenACC | CUDA |
---|---|
gangs | Blocks |
workers | Warps |
vectors | Threads |
OpenACC 的线程模型与 CUDA 的线程模型类似,但添加了一个并行的维度。 OpenACC 可以分为 gang 、worker 和 vector 三个并行层次。在上层, gang 类似于 CUDA 线程块。一个 gang 可包含一个或多个执行的线程,在每个 gang 内部都包含一个或多个 worker 。在 CUDA 中,一个 worker类似于线程中的一个线程束。每个 worker 都有一个向量宽度,由一个或多个同时执行相同指令的向量元素组成。毎个向量元素都类似于一个CUDA 线程,因为它是一个单一的执行流。 Op