0%

tensorflow

TensorFlow读取数据的方式主要有2种,一般选择错误会造成性能问题,两种方式为:

  1. Feed_dict 通过feed_dict将数据喂给session.run函数,这种方式的好处是思路很清晰,易于理解。缺点是性能差,性能差的原因是feed给session的数据需要在session.run之前准备好,如果之前这个数据没有进入内存,那么就需要等待数据进入内存,而在实际场景中,这不仅仅是等待数据从磁盘或者网络进入内存的事情,还可能包括很多前期预处理的工作也在这里做,所以相当于一个串行过程。而数据进入内存后,还要串行的调用PyArrayToTF_Tensor,将其copy成tensorflow的tensorValue。此时,GPU显存处于等待状态,同时,由于tf的Graph中的input为空,所以CPU也处于等待状态,无法运算。

  2. RecordReader 这种方式是tf在Graph中将读取数据这个操作看做图中一个operation节点,减少了一个copy的过程。同时,在tf中还有batch与threads的概念,可以异步的读取数据,保证在GPU或者CPU进行计算的时候,读取数据这个操作也可以多线程异步执行。静态图中各个节点间的阻塞:在一个复杂的DAG计算图中,如果有一个点计算比较慢时,会造成阻塞,下游节点不得不等待。此时,首先要考虑的问题是图中节点参数所存储的位置是否正确。比如如果某个计算节点是在GPU上运算,那么如果这个节点所有依赖的variable对象声明在CPU上,那么就要做一次memcpy,将其从内存中copy到GPU上。因为GPU计算的很快,所以大部分时间花在拷贝上了。总之,如果网络模型比较简单,那么这种操作就会非常致命;如果网络结构复杂,比如网络层次非常深,那么这个问题倒不是太大的问题了。

参考资料

  1. 深度学习在美团搜索广告排序的应用实践