performance guide建议在CPU上进行预处理而不是在GPU上进行预处理。列出的原因是
我不确定是否理解这两个论点。
我当然假设预处理不会导致数据大小的急剧减少(例如,超级采样或裁剪到更小的尺寸),在这种情况下,到设备的传输时间的增益是显而易见的。我认为这些是相当极端的情况,并不构成上述建议的基础。
有人可以理解这个吗?
答案 0 :(得分:8)
它基于CPU和GPU工作原理的相同逻辑。 GPU非常擅长重复并行化任务,而CPU擅长其他计算,这需要更多的处理能力。
例如,考虑一个程序,该程序接受来自用户的两个整数的输入并运行for循环100万次以对这两个数字求和。
我们如何通过CPU和GPU处理相结合来实现这一目标?
我们做初始数据(两个用户输入整数)从CPU上的用户拦截部分,然后将两个数字发送到GPU和for循环以对GPU上运行的数字进行求和,因为这是重复的,可并行化的简单的计算部分,GPU更擅长。 [虽然这个例子与tensorflow并不完全相关,但这个概念是所有CPU和GPU处理的核心。关于你的查询:输入图像上的随机裁剪,翻转和其他标准预处理步骤等处理能力可能不是计算密集型的,但GPU在这种中断相关计算方面也不擅长。]
我们需要记住的另一件事是CPU和GPU之间的延迟在这里起着关键作用。 与CPU内部不同缓存级别之间的数据传输相比,复制和传输来回CPU和GPU的数据是昂贵的。
正如Dey,2014 [1]提到:
当在GPGPU上计算并行化程序时,首先是数据 从内存复制到GPU,并在计算后数据 使用PCI-e总线从GPU写回内存(参见 图1.8)。因此,对于每次计算,都必须将数据复制到和 来自设备主机内存。虽然计算速度非常快 GPGPU,但由于设备 - 主机 - 内存之间的差距所致 通过PCI-e进行通信,性能的瓶颈在于 生成。
出于这个原因,建议:
您在CPU上执行预处理,CPU在其中执行初始操作 计算,准备和发送重复的其余部分 将任务并行化到GPU以进行进一步处理。
我曾经开发过缓冲机制来增加CPU和GPU之间的数据处理,从而减少CPU和GPU之间延迟的负面影响。看看这篇论文,以便更好地理解这个问题:
现在,回答你的问题:
为什么预处理会将结果发送回CPU,尤其是如果所有节点都在GPU上?
引自Tensorflow [2]的效果指南,
当在GPU上进行预处理时,数据流是CPU - > GPU (预处理) - > CPU - > GPU(培训)。数据被退回并且 在CPU和GPU之间。
如果您还记得上面提到的CPU-Memory-GPU之间的数据流图,那么在CPU上进行预处理的原因会提高性能,因为:
在性能指南本身中,它还提到通过这样做,并拥有一个高效的输入管道,你不会饿死CPU或GPU或两者,这本身就证明了上述逻辑。同样,在相同的性能文档中,您还会看到提及
如果使用SSD与HDD进行存储时,训练循环运行得更快 你的输入数据,你可能是I / O瓶颈。如果这是 例如,您应该预处理您的输入数据,创建一些大的 TFRecord文件。
这再次尝试提及相同的CPU-Memory-GPU性能瓶颈,如上所述。
希望这会有所帮助,如果您需要更多说明(关于CPU-GPU性能),请不要犹豫,留言!
<强>参考文献:强>
[1] Somdip Dey,有效的数据输入/输出(I / O),用于图形处理单元(GPU)的有限差分时域(FDTD)计算,2014
[2] Tensorflow效果指南:https://www.tensorflow.org/performance/performance_guide
答案 1 :(得分:2)
我首先引用performance guide中的两个论点,我认为 你的两个问题分别涉及这两个论点。
数据在CPU和GPU之间来回反弹。 ... 另一个好处是CPU上的预处理可以释放GPU时间,专注于培训。
(1)文件reader
,queue
和dequeue
等操作只能在CPU中执行,reshape
,cast
,{{1}等操作可以在CPU或GPU中。所以你的第一个问题就是猜测:如果代码没有指定per_image_standardization
,程序将由读取器在CPU中执行,然后在GPU中预处理图像,最后在CPU中排队和出列。 (不确定我是否正确。等待专家验证......)
(2)对于第二个问题,我也有同样的疑问。当您训练大型网络时,大部分时间都花费在巨大的卷积和梯度计算上,而不是预处理图像上。但是,当它们意味着 6X +样本/秒处理增加时,我认为它们意味着对MNIST的培训,其中通常使用小型网络。这是有道理的。较小的卷积花费的时间少得多,因此花在预处理上的时间相对较长。在这种情况下, 6X +增加是可能的。但是/cpu:0
是一个合理的解释。
希望这可以帮到你。