【问题标题】:Bench marking of PyOpenCL programsPyOpenCL 程序的基准测试
【发布时间】:2014-10-29 03:10:36
【问题描述】:

我一直在尝试使用 PyOpenCL 在 GPU 上对我的 FFT 程序进行基准测试。在使用 OpenCL 的“分析”和 python 的“时间”模块时,我看到了完全不同的结果。要使用分析,我会这样做,

queue = cl.CommandQueue(ctx,properties=cl.command_queue_properties.PROFILING_ENABLE)
<other codes>
for i in range(N):
  events.append(prg3.butterfly(queue,(len(twid),),None,twid_dev,<buffers>))
  events[i].wait()
for i in range(N):
  elapsed = elapsed + 1e-9*(event[i].profile.end - event[i].profile.start)
print elapsed

虽然时间模块可以这样使用,

k=time.time()
for i in range(N):
  event = prg3.butterfly(queue,(len(twid),),None,twid_dev,<buffers>)
print time.time()-k

由于这两个在 N=20 时给出完全不同的结果(而答案保持不变且正确!),我有以下问题。

  1. 事件分析究竟做了什么,它是否增加了在 event.wait() 中花费的时间?
  2. 由于在情况 2 中没有 event.wait() 的答案是相同的,因此仅执行内核所花费的时间是否正确?

请告诉我在 python 中对 OpenCL 程序进行基准测试的正确方法。

【问题讨论】:

    标签: python-2.7 opencl benchmarking pyopencl


    【解决方案1】:

    您的第二种情况仅捕获将内核排入队列所花费的时间,而不是实际运行它。一旦内核调用被放入队列中,这些入队内核调用就会返回 - 内核将与您的主机代码异步运行。要同时计时内核执行,只需添加一个调用以等待所有排队的命令完成:

    k=time.time()
    for i in range(N):
      event = prg3.butterfly(queue,(len(twid),),None,twid_dev,<buffers>)
    queue.finish()
    print time.time()-k
    

    您的第一种情况是正确计时内核执行所花费的时间,但在每次内核调用之间不必要地阻塞主机。将所有命令排入队列后,您可以再次使用 queue.finish()

    for i in range(N):
      events.append(prg3.butterfly(queue,(len(twid),),None,twid_dev,<buffers>))
    queue.finish()
    for i in range(N):
      elapsed = elapsed + 1e-9*(event[i].profile.end - event[i].profile.start)
    print elapsed
    

    这两种方法应该返回几乎相同的时间。

    【讨论】:

    • 谢谢,这很有道理。但没有 event.wait() 或 queue.finish() ,我能够获得正确的答案。因此,内核必须在那个时间本身执行并且输出准备好被复制到主机。有cmets吗?
    • @KarthikHegde 是的 - 当您将数据复制回主机时(例如,使用阻塞读取操作),这将强制完成所有先前提交的命令。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    相关资源
    最近更新 更多