Поскольку C ++ 11 не имеет future.then
Я начал использовать concurrency::task
от Microsoft PPL
библиотека. Это прекрасно работает большую часть времени.
Тем не менее, сейчас я нахожусь в ситуации, когда я делаю GPGPU, так что запланировано продолжение в PPL
Планировщик вызывает ненужную задержку, когда графический процессор простаивает.
Мой вопрос заключается в том, есть ли возможный обходной путь для concurrency::task
а также concurrency::task::then
чтобы их казнили напрямую.
Насколько я понимаю, регулярное запланированное задание в большинстве случаев будет выполняться сразу же по причинам эффективности кэша. Однако это не относится к задачам, которые были запланированы из явного потока (то есть потока GPU) с использованием concurrency::task_completion_event
,
Пример того, что я делаю:
template<typename F>
auto execute(F f) -> concurrency::task<decltype(f())>
{
concurrency::task_completion_event<decltype(f())> e;
gpu_execution_queue_.push([=]
{
try
{
e.set(copy(f())); // Skipped meta-template programming for void.
}
catch(...)
{
e.set_exception(std::current_exception());
}
});
// Any continuation will be delayed since it will first be
// enqueued into the task-scheduler.
return concurrency::task<decltype(f())>(std::move(e));
}
void foo()
{
std::vector<char> data /* = ... */;
execute([=]() -> texture
{
return copy(data)
})
.then(concurrency::task<texture> t)
{
return execute([=]
{
render(t.get());
});
})
.get();
}
Весь смысл .then заключается в выполнении блока кода, который зависит от завершения предыдущего блока. Если это не так, то вам не следует использовать .then, во-первых, вы просто должны написать встроенный код. Если, с другой стороны, вы действительно зависите от завершения предыдущего блока, нет другого выбора, кроме как ждать его завершения. Я должен что-то упустить.
Джо
Планировщик PPL не дает никаких гарантий относительно того, когда исполняется лямбда .then или в каком потоке он выполняется. Вы можете рассматривать его как отдельную задачу, запуск которой запланирован только после завершения предыдущей. Планировщик может выполнить задачу продолжения немедленно, он может даже использовать тот же поток, но это не является определенным.
Для обсуждения реализации планировщика смотрите:
Приложение А. Планировщик задач и менеджер ресурсов
Последние документы MSDN также содержат дополнительную информацию: