// 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。
IsExpensive
应该是false, true
时,是否有任何特定的指南? AsyncOp
(如RemoteFusedGraphExecuteOp
)都很昂贵,但MPIAllgatherOp
似乎并不昂贵。这不是矛盾吗?我问,因为IdentityOp
被明确标记为便宜。我想知道,是否也应该在自定义操作中覆盖此方法,因为每个CPU版本(甚至任何自定义代码)都被标记为昂贵。
XLA的整个逻辑似乎与an instruction is expensive无关。因此,这可能是需要考虑的重要部分。因此,关于真/假的抛硬币可能不是决定我的自定义操作中返回值的最佳方法。
答案 0 :(得分:9)
在回答您的问题之前,我认为值得尝试了解TensorFlow如何使用线程来完成您的工作。为此,建议您阅读this related and very good SO post。
您会发现TensorFlow使用线程池来完成工作。昂贵的Ops被安排在线程池中执行,而廉价的Ops被“内联”执行,这是由计划任务的同一线程执行的(注:在链接的源文件中,您仅发现一个异常,即当inline_ready
队列为空,线程可以自己执行最后一个昂贵的Op。)
考虑到这一点,让我们尝试回答您的问题。
- IsExpensive为假,为真时,是否有任何特定的准则?
我在TensorFlow手册中找不到特定的指南,但是,从我们上面讨论的内部来看,当将任务调度到线程池的偏移量与可忽略的操作相比时,应该将Op标记为昂贵的需要执行任务的时间。
- 如果将某项操作标记为昂贵操作会有什么影响?到目前为止,我只能说,活动配置文件仅以此为提示?查询此属性的唯一地方是在调度程序中,但没有解释内联的含义。
效果如下所示,每次Ops IsExpensive
方法返回false
时,它都可能被推送到inline_ready
队列中,并可能阻止线程执行其他任务,从而使您的程序停顿。相反,如果Ops IsExpensive
方法返回true,则将其安排在线程池上执行,并且调度线程可以继续在流程循环中继续执行其任务。
- 与“ 1”一起使用。我应该在自定义操作中关心它吗?
我认为您应该关心并尝试尽可能多地推理Op的执行时间。之后,决定如何实现IsExpensive
方法。
- 尽管有道理,任何AsyncOp(例如RemoteFusedGraphExecuteOp)都是昂贵的,但MPIAllgatherOp似乎定义为并不昂贵。这不是矛盾吗?
不,这不是矛盾。如果您阅读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.
其中明确指出,为线程池安排此任务几乎只是开销。因此,以内联方式执行它很有意义。