Ответ 1
Прежде чем отвечать на ваши вопросы, я думаю, стоит попытаться понять, как TensorFlow использует потоки, чтобы выполнить вашу работу. Для этого я предлагаю вам прочитать эту связанную и очень хорошую публикацию SO.
Вы обнаружите, что TensorFlow использует пул потоков, чтобы заставить вас работать. Дорогие Ops планируются к исполнению в пуле потоков, тогда как дешевые Ops исполняются "inline", что означает тот же поток, который планирует задачи (Sidenote: из исходного файла, который вы связали, вы найдете только одно исключение, то есть когда очередь inline_ready
пуста, поток может выполнить последнюю дорогостоящую Op самостоятельно).
Имея это в виду, попробуем ответить на ваши вопросы.
- Существует ли какое-либо конкретное правило, когда IsExpensive должно быть ложным, правда?
Однако в руководстве TensorFlow я не нашел конкретного руководства, однако из внутренних частей того, что мы обсуждали выше, Op должен быть отмечен как дорогостоящий, когда смещение планирования задачи в пул потоков пренебрежимо по сравнению со временем, когда задача должна быть выполнена.
- Каков эффект, если операция отмечена как дорогостоящая? До сих пор могу только сказать, что активное профилирование использует это как подсказку? Единственное место, запрашивающее это свойство, находится в планировщике, но не объясняет, что значит быть встроенным.
Эффект следующий: каждый раз, IsExpensive
метод Ops IsExpensive
возвращает false
он может быть перенесен в очередь inline_ready
и может блокировать поток от выполнения дальнейших задач, что останавливает вашу программу. Напротив, если метод Ops IsExpensive
возвращает true, он будет запланирован для выполнения в пуле потоков, и поток планирования может продолжать выполнять свои задачи в цикле процесса.
- В сочетании с "1." Должен ли я беспокоиться об этом в моих собственных Ops?
Я думаю, вам стоит позаботиться и попытаться как можно больше рассуждать о времени исполнения вами 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.
В чём четко говорится, что планирование этой задачи для пула потоков будет почти только накладными. Поэтому выполнение его inline имеет большой смысл.