有没有办法分析 OpenCL 或 pyOpenCL 程序?

Is there a way to profile an OpenCL or a pyOpenCL program?

我正在尝试优化 pyOpenCL 程序。出于这个原因,我想知道是否有一种方法可以分析程序并查看大部分时间需要做什么。

你知道如何解决这个问题吗?

提前致谢
安迪

编辑:例如,用于 CUDA 的 nvidias nvprof 可以用于 pyCuda,但不能用于 pyOpenCL。

是的,绝对有 - 您可以在设备上分析单个 PyOpenCL 事件 运行,也可以在主机上分析整个程序。

PyOpenCL 事件通过将内存复制到设备,运行在设备上安装内核,然后从设备复制内存来返回。

下面是分析设备事件的示例:

event = cl.enqueue_copy(queue, np_array, cl_array)
event.wait()
print (event.profile.end-event.profile.start)*1e-9

这是在主机上进行分析的示例:

from time import time, strftime, gmtime
start_time = time()
# ... do some stuff like the above ^
end_time = time()
print strftime('%H:%M:%S', gmtime(end_time - start_time))

我还没有看到更全面的分析 PyOpenCL 程序的方法。希望对您有所帮助!

好的,
我想出了一个办法:Cuda Toolkit 3.1 提供了 openCL 的分析(更高版本不会)。从此包中使用 compute visual profiler,即 (computeprof.exe)。它适用于 windows 和 linux here,并且可以与新的 Cuda 工具包一起安装。
它看起来像这样:

我希望这对其他人也有帮助。

基本上,Nvidia 的 Visual Profiler (nvvp) 曾经用于分析 OpenCL(甚至通过 pyopenCL),但 Nvidia 停止更新它。有一个巧妙的技巧,我从 pyopenCL 邮件列表中提取并使用 here 中的信息开始使用 nvvp。

基本步骤是:

  1. 创建一个 nvvp.cfg 文件,其中包含可视分析器的配置。

示例:

profilelogformat CSV
streamid
gpustarttimestamp
gpuendtimestamp
gridsize
threadblocksize
dynsmemperblock
stasmemperblock
regperthread
memtransfersize
  1. 创建一个 bash 脚本来设置环境变量并启动 python / OpenCL / pyOpenCL 进程。

示例:

#!/bin/bash
export {CL_,COMPUTE_}PROFILE=1
export COMPUTE_PROFILE_CONFIG=nvvp.cfg
python OpenCL_test.py

这将在您的工作目录中放置一个日志文件,您可以查看该文件。如果将 "OPENCL_" 的每次出现都更改为 "CUDA_",则可以将此文件导入 nvvp。有关详细信息,请按照提供的 link.

AMD 的 CodeXL 运行良好。

除了 之外,您还应该通过

创建命令队列来启用它的分析
queue = cl.CommandQueue(context, 
            properties=cl.command_queue_properties.PROFILING_ENABLE)

PyOpenCL examples 包含执行一些基本分析的基准测试脚本(检查 benchmark.pydump-performance.pytranspose.py)。