为什么要在CPU而不是GPU上进行预处理?

时间:2017-06-05 20:55:51

标签: tensorflow

performance guide建议在CPU上进行预处理而不是在GPU上进行预处理。列出的原因是

  1. 这可以防止数据再次从CPU转移到GPU再转发到GPU。
  2. 这使得这些任务的GPU可以专注于培训。
  3. 我不确定是否理解这两个论点。

    1. 为什么预处理会将结果发送回CPU,尤其是如果所有节点都在GPU上?为什么预处理操作而不是图上的任何其他操作,为什么它们/它们应该是特殊的?
    2. 尽管我理解让CPU工作而不是保持闲置的理由,但与训练步骤必须要做的巨大卷积和其他梯度反向传播相比,我会假设随机裁剪,翻转和其他标准预处理输入图像上的步骤应该在计算需求方面不远,并且应该在很短的时间内执行。即使我们认为预处理主要是移动的东西(裁剪,翻转),我认为GPU内存应该更快。然而,根据相同的指南,在CPU上进行预处理可以使吞吐量 6 +倍增加
    3. 我当然假设预处理不会导致数据大小的急剧减少(例如,超级采样或裁剪到更小的尺寸),在这种情况下,到设备的传输时间的增益是显而易见的。我认为这些是相当极端的情况,并不构成上述建议的基础。

      有人可以理解这个吗?

2 个答案:

答案 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进行通信,性能的瓶颈在于   生成。

enter image description here

出于这个原因,建议:

  

您在CPU上执行预处理,CPU在其中执行初始操作   计算,准备和发送重复的其余部分   将任务并行化到GPU以进行进一步处理。

我曾经开发过缓冲机制来增加CPU和GPU之间的数据处理,从而减少CPU和GPU之间延迟的负面影响。看看这篇论文,以便更好地理解这个问题:

EFFICIENT DATA INPUT/OUTPUT (I/O) FOR FINITE DIFFERENCE TIME DOMAIN (FDTD) COMPUTATION ON GRAPHICS PROCESSING UNIT (GPU)

现在,回答你的问题:

为什么预处理会将结果发送回CPU,尤其是如果所有节点都在GPU上?

引自Tensorflow [2]的效果指南,

  

当在GPU上进行预处理时,数据流是CPU - > GPU   (预处理) - > CPU - > GPU(培训)。数据被退回并且   在CPU和GPU之间。

如果您还记得上面提到的CPU-Memory-GPU之间的数据流图,那么在CPU上进行预处理的原因会提高性能,因为:

  • 在GPU上计算节点后,数据将被发送回内存 并且CPU获取该内存以供进一步处理。 GPU没有 足够的内存(在GPU本身上)以保留其上的所有数据以用于计算目的。所以 来回数据是不可避免的。为了优化此数据流,您 在CPU上进行预处理,然后为可并行化的任务准备的数据(用于培训目的)被发送到内存和GPU 获取预处理数据并对其进行处理。

在性能指南本身中,它还提到通过这样做,并拥有一个高效的输入管道,你不会饿死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)文件readerqueuedequeue等操作只能在CPU中执行,reshapecast,{{1}等操作可以在CPU或GPU中。所以你的第一个问题就是猜测:如果代码没有指定per_image_standardization,程序将由读取器在CPU中执行,然后在GPU中预处理图像,最后在CPU中排队和出列。 (不确定我是否正确。等待专家验证......)

(2)对于第二个问题,我也有同样的疑问。当您训练大型网络时,大部分时间都花费在巨大的卷积和梯度计算上,而不是预处理图像上。但是,当它们意味着 6X +样本/秒处理增加时,我认为它们意味着对MNIST的培训,其中通常使用小型网络。这是有道理的。较小的卷积花费的时间少得多,因此花在预处理上的时间相对较长。在这种情况下, 6X +增加是可能的。但是/cpu:0是一个合理的解释。

希望这可以帮到你。