' '

1. Tasks

In order to facilitate the implementation of a multithreaded ray tracer, we introduced the concept of tasks. A task is an independent unit of work. Two tasks should be able to be performed in any order without it affecting the results. This very property allows us to distribute tasks among CPU cores without worries.

Task Class
// In tasks/tasks.h

class Task
{
public:
    virtual void perform() = 0;
};
Note

In the case of our ray tracer, a task corresponds to one row of pixels. You can find the code responsible for creating tasks in renderers/renderer-base.h.

2. Task Schedulers

A task scheduler takes a list of tasks and performs each of them. No guarantees are made about the order in which it performs them.

TaskScheduler Implementation
// In tasks/task-scheduler.h

class TaskSchedulerImplementation
{
public:
    virtual void perform(std::vector<std::shared_ptr<Task>> tasks) const = 0;
};

3. Serial Task Scheduler

The start codes comes with SerialTaskScheduler, a task scheduler that performs the tasks in sequential order. Take a look at the code in tasks/serial-task-scheduler.cpp: you’ll see that it is nothing but a loop.