Re: [Algorithms] General purpose task parallel threading approach
Brought to you by:
vexxed72
|
From: Mat N. <mat...@bu...> - 2009-04-13 17:42:59
|
Again, there is a tremendous difference between allowing dynamic task dependencies within a frame vs. between frames vs. not at all.
Although it's really a matter of whether you can separate how you generate dependencies between tasks from running the task. If you can, then it doesn't matter when you spawn them, so you should spawn them where you can get the most benefit with the least complexity. If you can't, then you have to make an even better scheduler just to take into account intra-frame tasks.
Of course it doesn't work with a C++-vtable-dispatch mechanism; that does not allow you to separate the behavior of the task from the structure (i.e., dependencies) of the task. What Jon is talking about (I presume) is that tasks are not just vtables or function pointers; they have information associated with them that allows for higher order reasoning without running them.
MSN
From: Sebastian Sylvan [mailto:seb...@gm...]
Sent: Monday, April 13, 2009 10:09 AM
To: Game Development Algorithms
Subject: Re: [Algorithms] General purpose task parallel threading approach
On Mon, Apr 13, 2009 at 5:30 PM, Mat Noguchi <mat...@bu...<mailto:mat...@bu...>> wrote:
> Which is what I've been trying to say all this time. If the scheduler can't handle dynamic code, then it's not really a general system.
That's like saying if you can't handle dynamic allocations your game isn't truly dynamic. Well, maybe not, but what Jon said does not necessarily lead to what you said. It simply means that any dynamic behavior changes what happens between frames, not within a frame. That does not necessarily restrict "dynamic" code from ever working, just the mechanisms through which it can work.
This seems like a semantics argument, to be honest.
In my opinion a task system that places restrictions (fairly severe ones IMO) on what kinds of code you can run in tasks can not reasonably be called a "general" system. I don't find this to be an unreasonable definition.
This is more like "if you system can't handle dynamic allocations then it can't run code that really needs to allocate dynamically, which means it's a specialized, not general, system" which I would say is a fair, and even obvious, description.
Being able to run a different statically known control flow from frame to frame is not the same as being able to run dynamic control flow. I'm not sure you realize the severity of the restrictions you must put up with if the dependencies of a task must be known ahead of time - for example you couldn't do this in a task:
void MyClass::MyTask()
{
IFoo foo = GetFoo(m_dynamicData); // expensive, sequential
foo.bar(); // virtual function call; who knows what this does?
}
If bar is a virtual function this just wouldn't work within a system where the dependencies of MyTask have to be known up front before executing it, because there is no way of knowing up front what code will run when you call bar() (you have to run GetFoo to know what object you'll get back - you don't even know its type, just that it implements IFoo), and that code may have lots of dependencies that you simply can't know up front.
So for this code to work you'd have to guarantee that IFoo::bar() never spawns any child tasks, which is a pretty severe restrictions for a task parallel system (whose whole point is to facilitate running stuff in parallel) don't you think?
This doesn't mean you can't work around it for certain specific scenarios where dependencies are known up front, but it does mean that certain kinds of code are impossible to write and you'll just have to make do without them, which is not a characterization of a general system, IMO.
--
Sebastian Sylvan
+44(0)7857-300802
UIN: 44640862
|