21
\$\begingroup\$

While a library like SDL provides a cross-platform wrapper API for threading, I think it would be naive to assume that this leads directly to easy development of games across vastly different platforms (desktop / mobile).

What is the best way to tackle developing in this way (given any cross-platform threading API) considering the following:

  • different numbers of cores
  • vastly different processing capabilities per core
  • A generally different systems architecture with eg. different latencies for cache, RAM , and I/O access

I get the feeling that the only way to do this is evaluate how many threads may be run per each device you intend to support, and find out what the lowest common denominator is. However, this still leaves me in the dark as to the total amount of processing throughput available. Am I right in assuming the only way to do this effectively is to actively develop for the lowest spec mobile device I intend to support, throughout development? -- i.e. the lowest common denominator? Should this roughly be sufficient? Or is there more to it than this?

EDIT: Please could others offer further experience on this as I don't feel my question has been answered fully yet.

\$\endgroup\$
3
  • \$\begingroup\$ As my answer doesn't fully answer your question, could you detail what is missing / what you want to know? I might not be a great writer but I have handled this kind of problem more than once. \$\endgroup\$
    – Valmond
    Commented Aug 14, 2011 at 21:00
  • \$\begingroup\$ You really haven't answered the question, which was about about multithreading difficulties and how to overcome them when developing for platforms with different threading capabilities. See my paragraph below the bullet points. You talk about screen sizes and resolutions -- those have nothing to do with my question -- read the title. \$\endgroup\$
    – Engineer
    Commented Aug 24, 2011 at 15:00
  • 1
    \$\begingroup\$ I guess the difficulty comes from what you want to use the threads for. It's one thing to have a helper thread doing something on the side, and completely another to try to squeeze the last bits of performance from a 8-core machine.. The way I see it, the SDL threads are mostly meant for the first, not the latter. \$\endgroup\$ Commented Aug 25, 2011 at 10:16

3 Answers 3

11
\$\begingroup\$

You talk about "multithreading difficulties" but what difficulties are you actually talking about? In a way you're citing a phantom problem which may not even exist. The real challenge is one you make for yourself - if you are absolutely determined to get every last drop of power out of a piece of hardware, that does involve using the hardware to best effect, but that also widens the gap between the most powerful machine and the least powerful. The implication of this is that if you have a game that really makes the most of a PS3 (for example), you can't really run it on a cheap cellphone anyway, so your problem is no longer "how can I get 1 program to work across very different hardware" but becomes "how can I implement 1 game idea several different ways so that it works on differently powered hardware". The threading issue becomes less relevant then.

While a library like SDL provides a cross-platform wrapper API for threading, I think it would be naive to assume that this leads directly to easy development of games across vastly different platforms (desktop / mobile).

Easy development of games - sure. Optimal multithreading, no. But you don't need multithreading to make games. To make high performance ones, it certainly helps. But many great games run in a single thread.

What is the best way to tackle developing in this way (given any cross-platform threading API) considering the following:

  • different numbers of cores
  • vastly different processing capabilities per core
  • A generally different systems architecture with eg. different latencies for cache, RAM , and I/O access

Instead of trying to assign systems to threads, assign tasks to threads. Give each task the data it needs to run and farm the tasks off to whichever hardware is available. Usually you'll have some sort of thread pool to abstract away the various cores or processors, and a task manager which has a queue of tasks and yields them up to the various threads when the thread signals that it is finished the previous task and is ready for a new one. Hardware with more cores will obviously complete the tasks more quickly and be able to render more rapidly. Specialising this system to work optimally on systems with different characteristics becomes an advanced optimisation problem, but can be based on certain heuristics (eg. a task which doesn't need to return much data can easily be pushed to a different processor but one with a lot of data to return might need to be kept local).

However, decomposition of game features into discrete tasks is quite a complex matter and often not worth the effort unless you are very sure that you need the performance, so most won't even attempt it.

Some further reading:

http://www.gamasutra.com/view/feature/1830/multithreaded_game_engine_.php - see the 'data parallel' section. With this model the data is split across several identical tasks and farmed out to individual threads.

http://software.intel.com/en-us/articles/designing-the-framework-of-a-parallel-game-engine/ - quite dense, describes things at the OS level rather than the game level.

http://drdobbs.com/high-performance-computing/216500409 - not game specific, but completely relevant in terms of telling you how you need to divide up the tasks.

http://www.itfgaming.com/news/tech-focus-crysis-2-and-the-future-of-cryengine-3 - half-way down this interview is an anecdote about how they migrated to a task based system.

\$\endgroup\$
2
  • \$\begingroup\$ Very good points. And true, I used the word "difficulties" when "challenges" would be more accurate. You said, "Decomposition of game features into discrete tasks is quite a complex matter and often not worth the effort unless you are very sure that you need the performance, so most won't even attempt it." Can you elaborate on this? Provide sources? It's a bit vague but I'd say you're getting to the heart of the matter there. \$\endgroup\$
    – Engineer
    Commented Aug 24, 2011 at 23:17
  • \$\begingroup\$ Sorry, I thought this sort of approach was well known. I'll elaborate in the answer. \$\endgroup\$
    – Kylotan
    Commented Aug 25, 2011 at 9:52
4
\$\begingroup\$

When I did mobile games we first developed a 'gold' version (ie. a fully functionnal game) and then we split it up in 3 major versions (big screen, middle sized and small screen). These ones was further converted into 11 versions: demanding graphics (read takes much memory / cpu) vs low profile etc. (there were a couple 'special platform versions too).

The biggest problem was (that was my job among others) to isolate the platforms needed and determine those versions and how to create them (ie. big-screen but Low profile should be a downgraded version of big screen / hi profile or should it be middle sized screen / lo profile made big screen?).

Of course we coded with this in mind so games were very loosely attached to the screen size.

HTH

[edit] What I meant was that you need to split up your target platforms in different qualities (ie. 1 core, 2 cores, 1 core but twice as fast ...) Then decide how many virtual targets you want (for example "only one" or "Low, Mid, Hi") Then place all platforms in their respective 'quality' and for Each quality, take the lowest denominator and 'port' the code so it complies with those requirements (ie. works and is fast enough).

It might seem that you must do this with quite much guesswork but you can already find the worst quality with the worst platform. I'd choose every next quality at least "twice as good" as the former, this would probably not generate more than say 3-4 "qualities". If the code is ported from a gold version, any platform not performing good enough could just be retrograded to a lower 'quality' to make it speed up. Any new platform could also quite easily be placed in the right quality.

\$\endgroup\$
2
  • \$\begingroup\$ Off the top of your head, how much overhead time would you say that project had both in design and development phases, to accommodate for a multi-platform release like this? Just a rough average would help. \$\endgroup\$
    – Engineer
    Commented Aug 10, 2011 at 9:05
  • 1
    \$\begingroup\$ Well, as we did multi language (english, french, spanish, portugese, german and italian in a pack + whatever language needed by the day, taiwanese, turkish, russian...) and we had new platforms we needed to "port" all our games to every few months (read a new class of mobiles) we would actually have lost a lot of time not going this way, it would really have been impossible actually without a really big tem. The design of the 'framework' was done on the run as I learned about different mobiles and came to maturity after maybe 3-4 years. A well worth investment though. \$\endgroup\$
    – Valmond
    Commented Aug 10, 2011 at 11:27
2
\$\begingroup\$

I get the feeling that the only way to do this is evaluate how many threads may be run per each device you intend to support, and find out what the lowest common denominator is.

Not necessarily - there may be hope for a more dynamic solution, but this depends on the actual problem you are trying to solve (if any). You're a bit vague in your question, so my answer has to be vague as well.

If the grouping of platforms you are intending to run on have the capability for hardware enumeration via an API, you can use that interface to detect the maximum number of threads the system can handle, and use that as a basis for how many threads your application should create. The only challenge here is finding those APIs; whether or not you go to the OS level, or search for a third-party library, or a cross-platform SDK/API is up to you and depends on the platforms you are trying to support.

What is the best way to tackle developing in this way (given any cross-platform threading API) considering the following:

different numbers of cores
vastly different processing capabilities per core
A generally different systems architecture with eg. different

latencies for cache, RAM , and I/O access

In my opinion, none of those things should be your concern. Your concern should be building your game. If you hit a bottleneck and decide that it would be better to spawn a separate thread for a specific processor-intensive task, then spawn the thread and let the OS and other lower-level software decide how to manipulate the hardware to handle the threading.

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .