Sunday, October 9, 2011

yaTS - yet another Tasking System

Hello all,

some real posts after a *long* time. Well, basically, I want to only post anything related to some piece of software I write and publish.

So, I think I will publish a small serie of posts related to a small library I wrote: yaTS which is here:

http://code.google.com/p/yats/

As I am extremely lazy for this first post, I will mostly take what I wrote in tasking.hpp :)

The idea here is to present what the tasking system does.

Basically, a "tasking system" offers the possibility to schedule and asynchronously run functions in shared memory "system threads". This is basically a thread pool.

However, yaTS tries to propose more in this API by letting the user:
  1. Define *dependencies* between tasks
  2. Setup priorities for each task ie a higher priority task will be more likely executed than a lower priority one
  3. Setup affinities for each of them ie a task can be "pinned" on some specific hardware thread (typically useful when something depends on a context like an OpenGL context)
The core of this tasking system is a "Task". A task represents a function to call (to run) later. Each task can specify dependencies in two ways:
  1. "Start dependencies" specified (see below) by Task::starts. Basically, to be able to start, a task must have all its start dependencies *ended*
  2. "End dependencies" specified (see below) by Task::ends. In that case, tgo be able to finish, a task must have all its end dependencies *ended*
So, task1->starts(task2) means that task2 cannot start before task1 is ended
Also, task3->ends(task4) means that task4 cannot end before task3 is ended
Note that each task can only start one task and can only end one task

Specifying dependencies in that way allows the user to *dynamically* (ie during the task execution) create a direct acyclic graph of tasks (DAG). One may look at the unit tests to see how it basically works.

yaTS also classicaly implements a TaskSet which is a function which can be run n times (concurrently on any number of threads). TaskSet are a particularly efficient way to logically create n tasks in one chunk.

So, yaTS is somehow similar in TBB or other tasking systems.
However, I tried hard to make it small and I tried to have a API which is not too complicated and also reasonably powerful.

As you may see in utests.cpp, writing dynamic graphs of tasks is easy. You may use classical continuation-like tasking systems or wait for a task completion.

You may "pin" some task onto a particular HW threads. This will be useful when dealing with graphics API or anything with a context attached to a thread.

In the next posts, I would like to present a bit the current implementation details. Later, and as soon as the code is started, I would like to present how we can use this library to design a "game-loop-less" game engine.

Ben

No comments: