尽管数据集上有多线程设置,但 TF 时间线显示串行执行

Posted

技术标签:

【中文标题】尽管数据集上有多线程设置,但 TF 时间线显示串行执行【英文标题】:TF Timeline shows serial execution despite multithreading settings on Dataset 【发布时间】:2017-12-01 15:37:00 【问题描述】:

我对 Tensorflow 比较陌生,仍在努力了解如何提高性能。我使用 TF Timeline 工具检查了我的代码的执行,我惊讶地发现执行看起来像是串行的,如下图所示:

下面的代码是我用来设置数据输入的:

filenames = tf.placeholder(tf.string, shape=[None])
dataset   = tf.data.TFRecordDataset(filenames, "ZLIB", 128 * 1024 * 1024)
dataset   = dataset.map(_parse_function, 13)
dataset   = dataset.batch(8192)
dataset   = dataset.prefetch(8192 * 3)
iterator  = dataset.make_initializable_iterator()
X, y      = iterator.get_next()

特别是,考虑到我已将map 上的工作线程数设置为 13(与我的硬件一致)并且还设置了等于 3 倍批量大小的预取,我本来希望 CPU 与GPU 和 CPU/GPU 传输时间。所以我的问题是:

    为什么这看起来是连续的?我是否误读了我所看到的内容? 我使用数据集的方式有问题吗?我知道最终应该调整批处理大小和预取大小以获得最佳性能,但是如果我根本看不到 CPU 与 GPU 的并行使用,那又有什么意义呢?

【问题讨论】:

我认为将 .prefetch(8192*3) 放在 .batch(8192) 之后会导致它缓冲 24000 个批次或 2000 万个样本。尝试颠倒顺序,使prefetchbatch 之前或仅在prefetch(3) 批次之前。这就是我这样做的方式,但是我在这里看到了一些问题,这些问题都是按照您发布的方式进行的,这开始让我自己怀疑。所以让我知道你发现了什么。 【参考方案1】:

配置文件看起来是连续的,因为_parse_function()(的并行调用)中的任何操作都未包含在时间线跟踪中。 IteratorGetNext 跟踪区域将与管道中的一些操作重叠,但 dataset.prefetch(8192 * 3) 意味着大部分工作将在后台线程中异步执行。

David Parks' comment 提出了一个很好的观点:8192 * 3 batches 的预取缓冲区大小可能比您需要的要大,并且可能会导致内存压力。通常将预取缓冲区大小设置为较小的值(例如 1 或 2)足以将预处理与训练重叠;我预计在那之后不久收益会递减。尝试将 num_parallel_calls 参数增加到 Dataset.map() 以查看这是否会增加训练的吞吐量。

【讨论】:

以上是关于尽管数据集上有多线程设置,但 TF 时间线显示串行执行的主要内容,如果未能解决你的问题,请参考以下文章

获取 InvalidArgumentError:NewRandomAccessFile 在自定义图像数据集上使用 tf.data 时无法创建/打开

尽管并行编译,Mex 文件仍串行执行

在整个数据集上或仅在训练数据上计算 TF-IDF?

STM32 & TLV5628 SPI 通信

R中的gbm崩溃

详解 | 还不懂串口通信?看这篇!