TensorFlow操作`IsExpensive()`的含义?

时间:2018-07-18 08:59:11

标签: c++ tensorflow

有一个method in OpKernel

 // Returns true iff this op kernel is considered "expensive". The
 // runtime may use this flag to optimize graph execution for example
 // to "inline" inexpensive kernels.
 virtual bool IsExpensive() { return expensive_; }

默认情况下,GPU are considered as inexpensive上的所有操作似乎都被标记为昂贵,而CPU,SYSL被标记为昂贵。

要弄清expensive的定义和效果有点困难。不是information in the guide

  1. IsExpensive应该是false, true时,是否有任何特定的指南?
  2. 如果将某项操作标记为昂贵操作会有什么影响?到目前为止,我只能说,主动配置使用此just as a hint ?查询此属性的唯一地方是in the scheduler,但没有说明 inline 的含义。
  3. 与“ 1”一起使用。我应该在自定义操作中关心它吗?
  4. 尽管有道理,任何AsyncOp(如RemoteFusedGraphExecuteOp)都很昂贵,但MPIAllgatherOp似乎并不昂贵。这不是矛盾吗?

我问,因为IdentityOp被明确标记为便宜。我想知道,是否也应该在自定义操作中覆盖此方法,因为每个CPU版本(甚至任何自定义代码)都被标记为昂贵。

XLA的整个逻辑似乎与an instruction is expensive无关。因此,这可能是需要考虑的重要部分。因此,关于真/假的抛硬币可能不是决定我的自定义操作中返回值的最佳方法。

1 个答案:

答案 0 :(得分:9)

在回答您的问题之前,我认为值得尝试了解TensorFlow如何使用线程来完成您的工作。为此,建议您阅读this related and very good SO post

您会发现TensorFlow使用线程池来完成工作。昂贵的Ops被安排在线程池中执行,而廉价的Ops被“内联”执行,这是由计划任务的同一线程执行的(注:在链接的源文件中,您仅发现一个异常,即当inline_ready队列为空,线程可以自己执行最后一个昂贵的Op。)

考虑到这一点,让我们尝试回答您的问题。

  
      
  1. IsExpensive为假,为真时,是否有任何特定的准则?
  2.   

我在TensorFlow手册中找不到特定的指南,但是,从我们上面讨论的内部来看,当将任务调度到线程池的偏移量与可忽略的操作相比时,应该将Op标记为昂贵的需要执行任务的时间。

  
      
  1. 如果将某项操作标记为昂贵操作会有什么影响?到目前为止,我只能说,活动配置文件仅以此为提示?查询此属性的唯一地方是在调度程序中,但没有解释内联的含义。
  2.   

效果如下所示,每次Ops IsExpensive方法返回false时,它都可能被推送到inline_ready队列中,并可能阻止线程执行其他任务,从而使您的程序停顿。相反,如果Ops IsExpensive方法返回true,则将其安排在线程池上执行,并且调度线程可以继续在流程循环中继续执行其任务。

  
      
  1. 与“ 1”一起使用。我应该在自定义操作中关心它吗?
  2.   

我认为您应该关心并尝试尽可能多地推理Op的执行时间。之后,决定如何实现IsExpensive方法。

  
      
  1. 尽管有道理,任何AsyncOp(例如RemoteFusedGraphExecuteOp)都是昂贵的,但MPIAllgatherOp似乎定义为并不昂贵。这不是矛盾吗?
  2.   

不,这不是矛盾。如果您阅读MPIAllgatherOp的评论,则会发现以下内容:

// Although this op is handled asynchronously, the ComputeAsync call is
// very inexpensive. It only sets up a CollectiveOpRecord and places it
// in the table for the background thread to handle. Thus, we do not need
// a TF pool thread to perform the op.

其中明确指出,为线程池安排此任务几乎只是开销。因此,以内联方式执行它很有意义。