基于指令的OpenACC编程模型,可以将C、c++和Fortran代码加载到加速器如gpu上。OpenACC模型使用一个类似OpenMP的体系结构和语法,这使得开发人员不需要初始化加速器或管理数据传输。 相比于低层次CUDA模型,该模型提供了一个框架,大大简化了在GPU上进行程序移植或编写。
即使简化开发模型,但总会遇到调试困难,所以今天我们将看看如何解决bug!
Allinea DDT可以让开发人员调试OpenACC代码如同调试CPU代码一样简单。 用户可以进入加速器代码,设置断点,并使用多维数组查看器(multi-dimensional array viewer)检查设备数据和更多东西。
在这篇文章中,我将介绍如何使用GPU OpenACC修改一个简单的矩阵乘法函数以及如何使用Allinea DDT检查该代码。 编译器可以用英伟达PGI。
下图说明了如何使用OpenACC语法在GPU上实现矩阵乘法。关键字pragma界定数据在CPU与GPU之间的传输范围,透过 kernels导语来定义可并行化的作业与形态。如果把这个算法重新 CUDA 改写,很容易就会多出几十行代码,并且需要深入了解GPU架构才办得到。
加速器代码中的错误来源
面向加速器的编程容易出现一些独特的新类型的错误:
· - 数据必须在设备中进行传输。 OpenACC自动化这个过程,并且隐藏起来,但是问题仍然会出现——有时用户创建的优化不幸产生同步或重叠的问题。 使用Allinea DDT数组查看器可以看到在主机和设备上的数据。
· - 加速器通常有不同的内存设计。 这些不同类型的内存都可以通过Allinea DDT来检查——这样你就可以看到全局内存和共享内存之间的区别。
· - 加速器通常使用比CPU更多的线程,而且操作这些线程也不同。 使用Allinea DDT堆栈视图确切理解线程的行为——或者在较小的group里控制这些线程。
现在让我们把程序加载到Allinea DDT里。
我们在加速代码中设置一个断点。蓝色阴影部分显示不同线程的位置。我们在堆栈视图里可以看到执行路径里所有线程的位置。在这一点上,我们也可以设置监测点或者断点,就跟在CPU里一样,Allinea的执行行为也是一样的。Allinea DDT在GUI的顶部已经增加了CUDA线程窗口,改变特定线程块或线程的值,可以改变我们正在观察的线程,同时我们可以通过右边的变量视窗来观察变量中的I,j,k的值来得到证实。
加速器编程需要在设备中来回传输数,经常会出现错误,有了Allinea DDT数组查看器我们可以检查主机和GPU上的数据来确保正确执行数据转移。
利用OpenACC和Allinea DDT,科学家和工程师有一个强大的工具来利用加速器。 移植时间降低,大大减少代码的复杂性,同时简化了代码调试难度。