OpenCL profiling and debugging - OpenCL 分析与调试

Introduciton

使用OpenCL编写程序不应该局限于编写独立的高性能的内核,而是应该专注于应用程序的并行。之前本书介绍了如何根据设备的特征优化在设备上运行的内核。本章介绍了我们将介绍设备上进行计算的内核与主机之间的交互。我们需要对性能进行衡量,在整个应用程序中找到瓶颈。

一个OpenCL应用程序包括若干个内核以及主机和设备之间的IO。回答下列的一些问题,能够帮助我们提高应用程序的性能:

  • 有多个内核的应用程序中,应该优化哪一些内核?
  • 在执行之前,内核会在队列中等待多久?
  • 应用程序中,内核执行时间与初始化OpenCL、编译内核的时间之间的比例是多少?
  • 主机设备之间的IO用时与计算用时之间的比例是多少?
本章前两个部分分别介绍OpenCL中用于分析的API,以及如何使用操作系统的API来获得代码运行所用的时间。接下来的两个部分介绍AMD的两个工具,他们能帮助我们分析应用程序的性能:

  • AMD加速并行处理(Acceclerated Parallel Processing, APP)分析器(Profiler):是一个性能分析工具,它可以在应用程序执行时收集OpenCL运行时和AMD Radeon GPU的数据。
  • AMD加速并行处理内核分析器(KernelAnalyzer):一个静态的分析工具,可以用来为AMD Radeon GPU的OpenCL内核进行编译、分析和反汇编。
四种不同的方法能够帮助开发者快速地确定应用程序不能正常运行的原因,再加上十三章介绍的调试特征,能够很好的改善开发过程。

本章最后讨论调试OpenCL代码。调试并行程序通常比传统的顺序代码要复杂,因为像race condition之类的bug,很难检查到,也很难重现。

我们简单介绍了一个OpenCL调试和分析工具gDEBugger。同样介绍了AMD提供的printf的扩展,可以使用它来打印内核数据。

AMD加速并行处理分析器(AMD Acceclerated Parallel Processing Profiler)

AMD加速并行处理分析器是一个性能分析工具,它可以在应用程序执行过程中从OpenCL运行(runtime)和AMD Radeon GPU收集数据。我们能使用这些数据来查找应用程序中的瓶颈,并找到在AMD平台上优化性能的方法。后文中,AMD加速并行处理分析器简称为分析器。

分析器支持两种使用模式:

  1. Microsoft Visual Studio 2008或2010的插件
  2. 在Windows和Linux平台下均可以使用的命令行实用工具
推荐使用它Microsoft Visual Studio的插件,因为可以通过多种途径将结果进行可视化。作为插件使用时,只需在Visual Studio中载入一个解决方案,选择一个C/C++项目作为启动项,然后在"APP Profiler Session Explore"面板上点击"Collect Application Trace"或者"Collect GPU Performance Counters"。默认情况下,"APP Profiler Session Explore"面板和"Visual Studio Solution Explorer"面板在同一个窗口中。不需要修改代码或者项目。当应用程序完成,分析器会产生并显示得到的分析信息。

在没有源代码的情况下,命令行实用工具是获取应用程序数据的常用途径。分析器输出的文本文件可以直接用于分析,也可以载入到Visual Studio插件显示。

分析器支持两种操作模式:搜集OpenCL应用程序痕迹(trace)和手机OpenCL内核GPU性能计数器。

Collecting OpenCL Application Trace - 搜集OpenCL应用程序痕迹

OpenCL应用程序痕迹列出了应用程序进行的所有OpenCL API调用。分析器还记录了每一个API调用的输入参数,和输出结果。此外它还记录了主机代码的CPU时间戳,以及OpenCL运行中获得的设备时间戳。输出数据被存储在一个由AMD定义的、基于文字的文件格式中,叫做应用程序痕迹分析文件(Application Trace Profile file)。关于该文件格式的详细内容可以查看帮助文档。这个模式可以帮助我们理解一个复杂应用程序的搞基结构。

根据OpenCL应用程序痕迹数据中,我们可以:

  • 通过时间线视图(Timeline View)可以发现应用程序的高级结构。从这个视图中,我们能够确定应用程序中,OpenCL上下文和指令队列的个数,以及他们之间的关系。时间线中还显示了应用程序代码、内核执行和数据传输操作。
  • 通过总结页面视图(Summary Pages View)确定应用程序是否被内核执行或者数据传输所阻塞(bound),找到最耗时的10个内核和数据传输操作,找到应用程序中的API热点(调用最频繁的或最耗时的API调用)。
  • 通过API痕迹视图(API Trace View),查看并调试应用程序调用的所有API的输入参数和输出结果。

时间线视图提供了应用程序执行的直观表示。时间线的顶端是时间格(time grid),它显示了应用程序总的时间,当放到最大时,单位是毫秒。在应用程序进行第一个OpenCL调用的时候开始计时,到最后一个OpenCL调用结束。在时间格下方,列出了每个进行OpenCL调用的主机线程。沿着时间线列出了每个线程调用的OpenCL API,显示了每个API调用的开始时间和持续时间。在主机线程下面的OpenCL树显示了应用程序创建的所有上下文和队列,每个队列还有相应的数据传输操作和内核执行操作。时间线视图可以放大缩小、收起展开、选择感兴趣的区域。时间线视图中的API可以找到其在API痕迹中对应的API,反之亦然。

时间线视图是非常有用的。下面我们列举几个例子:

  • 可以在较高层次检查应用程序是否正确。通过检查时间线,你能验证应用程序创建的上下文和队列的数量。
  • 还可以确认应用程序的同步是否正确。比如,内核A执行时依赖于一个缓冲区操作和内核B执行后输出,那么在时间格中内核A应该在缓冲区操作和内核B执行完成之后。利用传统的调试技术很难发现这种类型的同步错误。
  • 最后,可以查看硬件的使用效率。比如,时间线应该显示独立的内核执行和数据传输操作同时发生。
Summary Pages View - 总结页面视图

总结页面视图显示了OpenCL应用程序的各种统计信息。它能估计应用程序的瓶颈的位置。同时还提供了一些有用的信息,比如每个上线问中,缓冲区对象和图像对象的数量,最耗时的内核调用等等。

总结页面视图包含了一下几个单独的页面:

  • API汇总页面:这个页面显示了应用程序中OpenCL API调用的统计,可以用于API热点的确定。
  • 上下文总结页面:该页面显示了没个上下文中内核发送和数据传输的统计,还包括每个上下文中,缓冲区对象和图像对象的个数。
  • 内核总结页面:该页面显示了应用程序中创建的内核的统计数据。
  • Top 10数据传输总结页面:该页面显示了最耗时10个的数据传输操作
  • Top 10内核总计页面:该页面显示了最耗时的10个内核执行操作。
从这些总结页面,可以确定内核执行和数据传输是否限制了应用程序的执行。如果是,可以找出那个设备是瓶颈。从讷河总结页面,我们可以找到执行时间最长的内核的名字。或者从Top 10内核总结页面,可以找到执行时间最长的内核实例。如果GPU设备上的内核执行时瓶颈,可以使用GPU性能计数器来内核内部的瓶颈。我们稍后会介绍GPU性能计数器。

如果数据传输制约了应用程序,从上下文总结页面可以找到最耗时的数据传输类型(读取、写入、拷贝或者映射)。对算法进行必要的修改,可能会将这类的数据操作减到最少。同时利用时间线视图,我们可以确定数据传输是否是最高效的,也就是,和一个内核执行并发执行。

API Trace View - API痕迹视图

API痕迹视图显示了应用程序中所有的OpenCL API调用。

每个调用了OpenCL主机线程对应一个单独的标签页,每个标签包含了该线程所调用的所有API,并列出了次调用的的相关信息:调用序号(代表执行的顺序)、API函数名、由分号分隔的参数列表、函数返回值。在显示参数的时候,分析器会尝试对指针进行解引用,对枚举类型进行解码以便列出尽可能多的、关于输入和输出的信息。双击API痕迹视图中的项可以在时间显示图中放大对应的API调用。

这个视图可以用来分析和调试每个API调用的输入和输出。比如,检查API是否返回CL_SUCCESS或者缓冲区创建时用的标识符是否正确。同时还可以在这个视图中发现重复的API调用。

Collecting OpenCL GPU Kernel Performance Counters - 搜集OpenCL GPU内核性能计数器

GPU内核性能计数器可以用来找内核执行的瓶颈。在帮助文档中列出AMD Radeon GPU支持的性能计数器列表。

只要使用痕迹数据来确定需要优化的内核,我们通过GPU性能计数器能够挖掘GPU设备上内核执行的数据。性能计数器能帮助我们:

  • 找到分配给内核的资源数量(通用计算注册器,局部存储大小和流控制堆栈大小),这些资源可能影响GPU中运行高峰的数量。高峰越多,可以更好的隐藏数据滞后。
  • 确定GPU执行的ALU、全局局部存储指令的数量。
  • 确定读存储和写入全局存储的字节数。
  • 确定系统中SIMD引擎和存储单元的利用率。
  • 显示了使用AMD GPU打包ALU指令到VLIW指令的过程中,着色器编译器的效率。
  • 在一个SIMD单元中的多道需要读写同一个LDS bank时,程序必须串行,从而导致访问延后。显示所有局部存储银行冲突(bank conflict)。
数据被输出到一个逗号分隔变量的格式的文件。你也可以点击"Method"栏中的内核名字,查看内核源代码,AMD Intermediate Language, GPU ISA, 或者 CPU assembly code。

AMD Accelerated Parallel Processing KernelAnalyzer - AMD加速并行处理内核分析器

AMD APP内核分析器是对OpenCL内核进行编译、分析并针对AMD Radeon GPU反汇编的静态工具。可以使用它的图形化的用户界面进行交互调试OpenCL内核,也可以用在命令行模式下使用它产生详细的报告。之后我们简称它为内核分析器。

在使用内核分析器之间,必须安装AMD OpenCL运行(runtime),而不需要GPU。

只需要将内核源代码键入内核分析器的主窗口即可,分析内核并不需要整个OpenCL应用程序。

使用内核分析器,我们可以:

  • 编译、分析和反汇编OpenCL内核,是针对多个Catalyst驱动版本和GPU设备目标。
  • 查看OpenCL运行产生的所有编译错误和警告。
  • 查看OpenCL运行时产生的AMD Intermediate Language code。
  • 查看AMD着色编译器产生的ISA代码。特别的,通过分析ISA代码,进行针对设备的内核优化。
  • 查看分析ISA代码产生的各种统计数据
  • 查看通用计算注册器,列出为内核分配的注册器。
因为内核分析器可以快速地针对多个GPU目标设备编译一个内核,在迅速确定OpenCL内核时它是非常有用的。

你可能感兴趣的:(OpenCL profiling and debugging - OpenCL 分析与调试)