在关于the performance of eager execution的tensorflow指南中,有一段代码如下:
import time
def measure(x, steps):
# TensorFlow initializes a GPU the first time it's used, exclude from timing.
tf.matmul(x, x)
start = time.time()
for i in range(steps):
x = tf.matmul(x, x)
_ = x.numpy() # Make sure to execute op and not just enqueue it
end = time.time()
return end - start
...
with tf.device("/cpu:0"):
print("CPU: {} secs".format(measure(tf.random_normal(shape), steps)))
with tf.device("/gpu:0"):
print("GPU: {} secs".format(measure(tf.random_normal(shape), steps)))
第二条注释之前的代码是什么意思:“ _ = x.numpy()”?
如果我注释掉这一行,是否不会在cpu / gpu上执行tf.matmul(x,x)?
答案 0 :(得分:1)
从技术上讲,可以在矩阵乘法完成之前返回对tf.matmul
的调用。
在实践中:
execution_mode=tf.contrib.eager.ASYNC
),则tf.matmul
仅在矩阵乘法完成后返回。tf.matmul
在对CUDA流进行矩阵乘法排队后返回(有关流的更多信息,请参见NVIDIA developer documentation) .numpy()
调用将结果复制回主机内存(因为numpy数组必须由主机而不是GPU内存支持)。为了正确地做到这一点,它必须等待CUDA流上排队的所有计算操作完成。因此,.numpy()
调用是确保“ CUDA流已处理”的一种方式。这样做的目的是确保end - start
负责完成操作所花费的时间,而不仅仅是将其排入CUDA流中。
也就是说,该代码段似乎高估了在GPU上执行的时间,因为它还包括每个步骤之后复制到主机的时间。该_ = x.numpy()
行应移至for循环之外,以获得更准确的度量(即执行矩阵乘法steps
次的时间,然后等待CUDA流完成,并复制到主机内存一次) )。理想情况下,我们可以排除复制回主机内存所花费的时间。
希望如此。