3

Since C++11 doesn't have a future.then I've started using concurrency::task from the Microsoft PPL library. It works great most of the time.

However, right now I'm in a situation where I'm doing GPGPU, so having .then continuations scheduled in the PPL scheduler causes unnecessary delay where the GPU is idle.

My question is whether there is any possible workaround for concurrency::task and concurrency::task::then to have them executed directly.

From my understanding a regularly scheduled task will in most cases execute it's continuation right away due to cache efficiency reasons. However, this is not the case for tasks that have been scheduled from an explicit thread (i.e. the GPU thread) using concurrency::task_completion_event.

An example of what I am doing:

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();
}
ronag
  • 49,529
  • 25
  • 126
  • 221
  • Your issue seems to stem from the need for multiple task queues that stand for different types of computational resources (CPUs vs GPUs) depending on the task type (the code to be executed). In PPL, this would involve use of the [Scheduler class](http://msdn.microsoft.com/en-us/library/dd492385.aspx). – rwong Jul 25 '13 at 21:55

2 Answers2

0

The whole point of .then is to execute a block of code that depends upon the previous block completing. If this isn't the case, then you should not be using .then in the first place, instead you should just write the code inline. If, on the other hand, you really do depend upon the previous block completing, there is no choice but to wait for it to complete. I must be missing something.

joe

Joe Greer
  • 19
  • 1
  • You are missing something. The problem is that the continuation is unnecessarily delayed by being enqueued into the task scheduler before being executed, instead of being executed directly. – ronag Jan 09 '13 at 20:21
0

The PPL scheduler makes no guarantees as when the .then lambda is executed, or what thread it is executed on. You can consider it as a separate Task that is scheduled to start only after the previous one has completed. The scheduler may execute the continuation task on immediately, it may even use the same thread but this it not a certainty.

For a discussion of the scheduler implementation see:

Appendix A: The Task Scheduler and Resource Manager

The latest MSDN docs also has some more information:

Task Scheduler (Concurrency Runtime)

Ade Miller
  • 13,575
  • 1
  • 42
  • 75