# OpenMP

This topic is 4349 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

There's a lot of talk about how multi-threading is the future of game programming. I think this has a lot of people worried since game-programming is generally not such a highly tested/designed branch of computer science - more of a "run it and see" philosophy - and time spent carefully examining MT code is saved many-fold in debugging. I'd never come across OpenMP until looking through some Intel docs - which is suprising since it allows automatic threading. Has it been discussed here and I missed it, or have people not found ways to make use of its (limited) abilities?

##### Share on other sites
I think it mostly hasnt been discussed because its not widely supported, for example you have to have better than the Express Edition versions of Visual Studio to use it with C++.

I've had a play with it, its pretty handy, however it doesnt interact with the C++ Std Lib. as such you end up having to write your own versions if you want std::for_each to use multiple threads.

I think it has some legs, but it will need better support, in the std lib in perticular, if its to get anywhere (of the top of my head I guess the compiler writers could use a system where, if you've enabled a pragma all loops which logically support it could use threading, but this could lead to bugs and other issues, perticulary if you leave a pragma open).

##### Share on other sites
OpenMP does *not* have a way to parallelize tasks, which is really what you want in games.

OpenMP's real power is in automatically parallelizing certain types of loops. This is useful in some types of numeric processing where you are basically moving a few billion array items from state one to state two.

It is very useful for image processing, complex audio signal processing, and other places where there is a lot of parallel processing possible in loops, with otherwise completely serial processing. The overhead of spawning /n/ threads, distributing the work, gathering the results, and terminating the threads is pretty big.

Regular multithreading (which is more common than your post implies) is used to separate out different aspects of the system that need to execute at different rates, or need to block, or otherwise can benefit from being in another thread.

A MT game can be designed to have minimal contact between threads (meaning less syncrhonization), and very strict in-house rules about accessing objects that are shared between threads. If you only lock an object periodically for making a local copy, then only use the local copy, it really isn't that bad. Most data has a clear owner with every other thread needing to view -- but not modify -- that data. Having multiple sources modify the data is when the problems start.

Also, you should probably know that many of the libraries (such as DirectSound, Direct3D, and networking) all have some multithreading built in. You can also take advantage of OS-provided multithreading with asyncrhonous disk reads, which can really help when loading data on the fly, and other asyncrhonous functions.

##### Share on other sites
Quote:
 OpenMP does *not* have a way to parallelize tasks, which is really what you want in games.

while(!GameOver){ #pragma omp sections {  #pragma omp section  {   DoUpdate();  }  #pragma omp section  {   DoRender();  } }}

I'm being a bit awkward, because functional decomposition (separate tasks multithreaded) IS the weakness of MP. But the simplicity of it is attractive.

Good point about STL, I'd not thought of that. The fact that MS are supporting it should push this type of thing forward though?

##### Share on other sites
Quote:
 Original post by d000hgThe fact that MS are supporting it should push this type of thing forward though?

Nope.

The target market for OpenMP is essentially people doing very time-expensive (multi-second) lockstep signal processing. It generates threads when the loop starts (which is time expensive) and closes them out when the loop ends (which is also very expensive). These are patterns we try to avoid in games.

Multithreaded engines really aren't as hard as people make them out to be when you design with a producer/consumer pattern. The producer is the ONLY thread allowed to modify the data, the consumers get a copy for their own use. Notify each thread when the data is updated, and you're good to go.

A little more work is required if your threads actively poll, but it's a tiny amount of locking and shouldn't be a major issue. If you do it too much you will get worse performance on multi-cpu machines since it takes a while for the locking to occur.

##### Share on other sites
Original post by d000hg
while(!GameOver){ #pragma omp sections {  #pragma omp section  {   DoUpdate();  }  #pragma omp section  {   DoRender();  } }}

Do you really want Update and Render going on concurrently with the same data? Do you really want record locks all over the place as shared data is accessed and modified? Or perhaps worse, perhaps no record locks, meaning your rendering will include non-updated and updated content mixed together?

Also it is bad design to have your rendering coupled with your processing. Certain players of Quake used something similar (varied physics speed) to their advantage. [smile]