【问题标题】:Measuring time using pycuda.driver.Event gives wrong results使用 pycuda.driver.Event 测量时间会给出错误的结果
【发布时间】:2012-09-04 07:52:27
【问题描述】:

我从 PyCuda 示例中运行 SimpleSpeedTest.py,产生以下输出:

Using nbr_values == 8192
Calculating 100000 iterations
SourceModule time and first three results:
0.058294s, [ 0.005477  0.005477  0.005477]
Elementwise time and first three results:
0.102527s, [ 0.005477  0.005477  0.005477]
Elementwise Python looping time and first three results:
2.398071s, [ 0.005477  0.005477  0.005477]
GPUArray time and first three results:
8.207257s, [ 0.005477  0.005477  0.005477]
CPU time measured using :
0.000002s, [ 0.005477  0.005477  0.005477]

前四个时间测量是合理的,但最后一个 (0.000002s) 距离很远。 CPU 结果应该是最慢的,但它比最快的 GPU 方法快几个数量级。所以显然测量的时间一定是错误的。这很奇怪,因为相同的计时方法似乎适用于前四个结果。

所以我从 SimpleSpeedTest.py 中获取了一些代码并制作了一个小的 测试文件 [2],它产生了:

time measured using option 1:
0.000002s 
time measured using option 2:
5.989620s 

选项 1 使用 pycuda.driver.Event.record()(如 SimpleSpeedTest.py)测量持续时间,选项 2 使用 time.clock()。同样,选项 1 关闭,而选项 2 给出了合理的结果(运行测试文件所需的时间约为 6 秒)。

有人知道为什么会这样吗?

由于 SimpleSpeedTest.py 支持使用选项 1,是否是我的设置导致了问题?我正在运行 GTX 470、显示驱动程序 301.42、CUDA 4.2、Python 2.7 64、PyCuda 2012.1、X5650 Xeon

[2] 测试文件:

import numpy
import time
import pycuda.driver as drv
import pycuda.autoinit

n_iter = 100000
nbr_values = 8192 # = 64 * 128 (values as used in SimpleSpeedTest.py)

start = drv.Event() # option 1 uses pycuda.driver.Event
end = drv.Event()

a = numpy.ones(nbr_values).astype(numpy.float32) # test data

start.record() # start option 1 (inserting recording points into GPU stream)
tic = time.clock() # start option 2 (using CPU time)

for i in range(n_iter):
    a = numpy.sin(a) # do some work

end.record() # end option 1
toc = time.clock() # end option 2

end.synchronize() 

events_secs = start.time_till(end)*1e-3
time_secs = toc - tic 

print "time measured using option 1:"
print "%fs " % events_secs
print "time measured using option 2:"
print "%fs " % time_secs

【问题讨论】:

  • 你没有在 GPU 上运行任何东西 (testfile2.py),那么你唯一要做的就是创建一个 numpy 数组。所以我猜drv.Event 衡量的是花在 GPU 上的时间,而不是 CPU。
  • @dav1d 是的,这很可能是问题所在。但如果是这种情况,为什么“SimpleSpeedTest.py”使用选项 1 来测量 CPU 计算所用的时间?
  • 我不知道,也许这是一个错误。由于它是一个 wiki,您可以编辑文件并修复它。
  • 感谢您给我发电子邮件。我确信当我发布代码(2 年前?)时,它有效。它在论坛中讨论过,所以我很确定这不是一个小错误(嗯,我希望如此)。也许pycuda现在以不同的方式处理时间?我使用的是早期的 CUDA(可能是 2?我记得后来升级到 CUDA3),而 pycuda 会年轻 2 岁(例如,我必须提交修复以支持复杂的 nbrs)。如果您修复它并提交一个工作版本,我会非常高兴,可能在 cmets 中包含一个示例输出(以帮助未来的调试会话)。伊恩。

标签: python time pycuda


【解决方案1】:

我联系了Andreas Klöckner,他建议也同步开始事件。

...
start.record()
start.synchronize()
...

这似乎解决了这个问题!

time measured using option 1:
5.944461s
time measured using option 2:
5.944314s 

显然 CUDA 的行为在过去两年发生了变化。我更新了SimpleSpeedTest.py

【讨论】:

  • 添加 start.synchronize() 等待 start.record() 操作被推送到 GPU 和 GPU 将时间戳写入内存。该代码似乎没有向 GPU 推送任何额外的工作。然后它使用 stop.record() 推送另一个 CUDA 事件并调用 stop.synchronize() 以等待 GPU 写入时间戳。这是一种非常不雅的方式来捕获 CPU,而不是 GPU 执行时间。如果您想使用高精度单调计时器捕获挂钟时间,我建议您查看 x86 时间戳计数器。这由 gettimeofday() 和 QueryPerformanceCounter (>=Win7) 使用。
猜你喜欢
  • 2016-08-29
  • 2018-02-04
  • 2018-10-12
  • 1970-01-01
  • 1970-01-01
  • 2020-12-11
  • 2019-07-04
  • 2012-12-06
  • 1970-01-01
相关资源
最近更新 更多