Windows Fibers

Started by
13 comments, last by Christer Ericson 16 years, 8 months ago
Hiya, I've been looking into Windows fibers, and thinking about how they could be used for tasks like AI and scripting in a game. It all seems pretty cool, each AI agent could run from it's own fiber, or perhaps each script. I've never used fibers before though, so I'm just wondering what you folks think about them? Are they suitable for this? I'm also wondering if there are any performance increases to be gained from using fibers? Anyhow, I'd like to implement a fiber-based system component for my project, mostly because I've not used them before, but that's not really a good enough reason on it's own... Any opinions are very welcome, thanks [smile] James.
Advertisement
Quote:Original post by beebs1
Hiya,

I've been looking into Windows fibers, and thinking about how they could be used for tasks like AI and scripting in a game. It all seems pretty cool, each AI agent could run from it's own fiber, or perhaps each script. I've never used fibers before though, so I'm just wondering what you folks think about them? Are they suitable for this?

I'm also wondering if there are any performance increases to be gained from using fibers?

Anyhow, I'd like to implement a fiber-based system component for my project, mostly because I've not used them before, but that's not really a good enough reason on it's own...

Any opinions are very welcome, thanks [smile]
James.

Fibers are a thing of the past. They are emulated threads that were nearly useful at the time of Windows 3.0. They cost a lot to manage (meaning that you'll get no performance gains), and are inferior to threads in many ways. The 11th commandment is "Thou shall not use fibers".

Use plain threads instead (or give a look to Intel TBB 2.0).
Quote:Original post by Emmanuel Deloget
Fibers are a thing of the past. They are emulated threads that were nearly useful at the time of Windows 3.0. They cost a lot to manage (meaning that you'll get no performance gains), and are inferior to threads in many ways. The 11th commandment is "Thou shall not use fibers".


Aren't they basically coroutines? From what I've read about coroutines, they're used for different purposes than threads - when you want logically distinct control flows but don't want them to run in parallel. It's a pity they're not a portable part of most programming languages.


Quote:Original post by Emmanuel Deloget
Fibers are a thing of the past. They are emulated threads that were nearly useful at the time of Windows 3.0. They cost a lot to manage (meaning that you'll get no performance gains), and are inferior to threads in many ways. The 11th commandment is "Thou shall not use fibers".

Use plain threads instead (or give a look to Intel TBB 2.0).

I agree with most of what you say but according to the MSDN, fibers have only been around since Windows 98 and NT 3.51 SP3.

Also, Raymond Chen wrote a small series which used fibers a few years back. In part 3 he mentions some of the hazards of fibers if used improperly (and why they are difficult to use properly).
Also, always remember that a thread does not necessarily mean parallel execution. You can only execute 1 thread simultaneously per core in your CPU (most have 1 core, the Core2 and other dual-core machines have 2, and some have 4). That's it for mainstream consumer CPUs.

That means that you'll never get a performance benefit from using more threads than your have cores. It costs performance to switch between threads. So the idea of each unit on it's own thread is an understandable idea (and a common one) but in practice is a very bad one.

You should certainly endeavor to make use of all existing cores. And threads can be useful to give the illusion to the player that things are happening at the same time (i.e. run audio in it's own thread, as well as networking). It just means that to a human things appear to happen simultaneously; to the computer it's just doing one thing for a while then switching context and doing another thing for a while.

-me
Quote:Original post by Emmanuel Deloget
Fibers are a thing of the past. They are emulated threads that were nearly useful at the time of Windows 3.0. They cost a lot to manage (meaning that you'll get no performance gains), and are inferior to threads in many ways.
That's so wrong in so many ways! Fibers/coroutines are not "emulated" threads and they are not inferior to threads; fibers address a completely different need. Fibers are cooperative, threads are preemptive. In that they're cooperative, fibers are arguably the most lightweight mechanism for multitasking: you save/restore registers, switching to a different stack inbetween. Threads typically need to issue kernel/OS calls to switch, and are much more heavyweight. Fibers are very much not a thing of the past!

Quote:Original post by beebs1
I've never used fibers before though, so I'm just wondering what you folks think about them? [...] I'm also wondering if there are any performance increases to be gained from using fibers?
Fibers are cool and yes there are performance increases to be had, potentially. Consider a system with a single execution unit (i.e. no hardware threading, or just one of several hardware threads). In situations where you would normally issue a synchronous call that you would have to wait for, you can instead issue the call asynchronously, switch to another fiber, and allow the system to continue executing. You can later Yield() back to the routine where you issed the asynchronous call, when the call has completed. No cycles went to waste, other than the fiber switch. If the cost of switching fibers is less than the cost of waiting synchronously, you're ahead.

You could of course issue the call asynchronously and poll for its completion manually in your code, but a fiber system is much more elegant and more user-friendly.

Threads and fibers can with benefit be used simultaneously. For instance, you start up as many threads as you have multiple hardware execution units. Then, within each thread and hardware unit you manage tasks with fibers rather than with threads. With the threads you make sure to utilize all hardware units, with the fibers you make sure to utilize "all" cycles within that hardware unit (instead of stalling for synchronous calls, RPC calls, etc).
I looked into fibers a while back, but found them redundant (thread stack per fiber).

I implemented my own cooperative multi-tasking model through the use of threads and async message passing (or non-blocking method invocation). I have micro-threads, which are just normal objects, and a thread pool, where each thread serves a subset of objects.

There are a few gotchas to look out for - infinite loop in one micro-thread will cause that entire worker thread to stall. But, this is only possible with a for/while loop, since all communication between threads is asynchronous, so an infinite loop made this way is quite common to ensure periodic processing.

One thing it does require though, and where the most complexity comes from, is lock-less queue for passing function calls between threads. Locking in this case would kill performance.

The resulting model has little to no performance penalty (in single thread, performance is just a tad slower than usual function pointers, like boost::signal), cross process communication is limited by characteristics of the queue, usually 10 times slower.

But - there are just about no problems running 1 million such micro-threads, and the whole system scales arbitrarily, just define a number of worker threads.
Quote:Original post by Palidine
[...]That means that you'll never get a performance benefit from using more threads than your have cores.[...]
There is an important distinction to be made: you'll never get a performance benefit from using many more active threads than you have cores. There are many situations where using more threads than cores is a good thing, such as i/o threads (especially I/O completion ports) that will block and not actually do anything on the cpu until the system finishes some significant task. It can make a great deal of sense to have something like N+2 threads for blocking tasks where N is the number that can actually run simultaneously. Some book on windows gives a complete argument and explanation for the fact, but I can't remeber which.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
Also, even if your 4-thread system is a little slower than optimal on a single core system, it scales to a 2/4 core system whereas your single-threaded version doesn't.
And of course, using threads makes some things just a lot easier. In applications programming we use loads of threads for things like DB access, remote calls, network stuff, when the main system must be highly responsive.
Bit of a shame perhaps, but I think you'd have to look far and wide to find a single person who has ever used fibers in a game.
As great as they may seem, good luck finding people to help you when you run into trouble. The coolness factor just doesn't cut it for me.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms

This topic is closed to new replies.

Advertisement