3
\$\begingroup\$

There is no cross platform way to set process priorities, and I don't want to use threads since there are no standard method of setting priority to certain threads, apart from the fact that threads are hard to use.

Let's say I have a task that takes a certain amount of computing time, which on my computer takes 10 seconds. This task usually takes a long time, like for example, loading geometry chunk dynamically, or opening a new audio ambience file. I don't need this task to be finished instantly because it's a big task so I can't afford to wait for a frame to finish, so I need to execute it over several frames, rather a certain amount of time.

Since I don't want to freeze the game, I can cut this loop into several batches and execute one batch per frame. If my game runs at 50 fps, a 10 second task can be divided in 500 batches. If my program loops over N*500 iterations, each batch loops over N iterations. If I don't want it impact others parts of my game, I can execute N/2 or even N/5 iterations per batch.

I'm not sure if I'm reinventing the wheel though, isn't there some C++ standard thing or programming pattern that allows me to do that already ? I'm not sure if it's optimal to cut a loop, and I'm not planning to use multithreading.

\$\endgroup\$
3
\$\begingroup\$

You can use the concept of Coroutines to execute a long task with other activities at the same time on a single thread. Basically it is a function which can yield execution control voluntarily. The next time it is called, execution will continue after the point where the function yielded last time. Implementing this in most compiled languages is tricky, because you have to save all CPU registers in use, as well as any local variables on the stack. Many scripting languages have support for coroutines right out of the box, however, especially ones that lack explicit support for threads. For instance, Lua.

Manually splitting your task up into 500 parts and trying to manage getting it to run correctly is likely going to be a nightmare, especially six months from now when you haven't worked on that code in four months and suddenly need to make some changes.

Despite having to deal with more issues (synchronization, memory barriers, and thread-local memory, etc) multithreading really is the easiest way to deal with this, and will yield the best performance in all likelihood. You can abstract away the platform-dependent code using a library like boost::thread or std::thread if you're using a C++11 compiler. You can deal with single-core processors by calling std::this_thread::yield() every so often in your low-priority tasks, or the equivalent in whatever library you use. Windows will typically give a running thread up to 10ms (most of a frame!) before forcing a context switch (if there are other waiting threads), but calling yield() is like saying "Okay, I know I've got more time, but I'm good for now, anyone else?".

So much of game programming does not lend itself easily to multithreading that it's easy to say "No Thanks," but modern processors are usually dual core with hyperthreading or quad-core, so not using those extra logical processors for something is just throwing away performance. The tasks you mentioned, (loading assets from disk) are some of the few tasks that are extremely easy to offload to other threads, since they don't require much access to shared memory.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.