Jump to content
  • Advertisement
Sign in to follow this  
serberus

Time Management

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi. I have several objects in my project. I have a loop in some thread: for(i=Objects.begin(); i != Objects.end(); ++i) { i.Think(); } In another thread: for(i=Objects.begin(); i != Objects.end(); ++i) { Report += i.GetResult(); } Report.Send(); Its all right if Think() is quick for all object. But, there is problem if some object think long time. The Report contains new result for some object and old result for anothers. How organize an even distribution for all object ?

Share this post


Link to post
Share on other sites
Advertisement
Game Programming Gems 3 has a great article on this. You should definately look into it. ("Scheduling game events".)

2 possible solutions i can think of:

1) multithread your game and run the thinking in the background.

2) record the average think time for objects and use that to "broker" think time. First organize your thinking objects by priority and then size (in think time). Objects that tend to take longer get allotted time first and then pack the leftover time with some objects that don't require so much. This means that you need to have a limit of time that you cannot exceed. Set your target and then broker the time out to different objects each frame. Once the time is "filled", do the thinking and get the other objects on the next frame in case you cannot get them all to think inside one single frame.

Another idea is to space out the thinking so that you don't do it every frame. You can build your time management system so that objects think() every X seconds or X frames or based on some arbitrary priority system instead, or both. With this approach you can have just a few objects think each frame instead of all of them at once. Imagine a cyclic queue where you only do a few eachf frame and the pop them onto the back again.

Share this post


Link to post
Share on other sites
For your particular example you are trying to parallelize two serial processes which will never work. You have step A(Think()) and step B(GetResults()). Those must occur serially. Therefore you can't have thread 1 do A and thread 2 do B and have it ever workout.

So what you need to do is re-work your algorithm into a parallel problem. There are many options. Here are a couple:

1) put half the objects in one thread, half in the other. Update all objects, wait at a barrier (both threads finish). Then get the results (in parallel maybe if the time saved threading is worth the cost of the locks or whatever to make your data store thread safe)

2) put half the objects in one thread and half in the other, in each thread, Think then GetResults and save them to a thread-safe data store.

-me

[Edited by - Palidine on December 24, 2008 2:29:12 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by leiavoia
Game Programming Gems 3 has a great article on this. You should definately look into it. ("Scheduling game events".)

2 possible solutions i can think of:

1) multithread your game and run the thinking in the background.

2) record the average think time for objects and use that to "broker" think time. First organize your thinking objects by priority and then size (in think time). Objects that tend to take longer get allotted time first and then pack the leftover time with some objects that don't require so much. This means that you need to have a limit of time that you cannot exceed. Set your target and then broker the time out to different objects each frame. Once the time is "filled", do the thinking and get the other objects on the next frame in case you cannot get them all to think inside one single frame.

Another idea is to space out the thinking so that you don't do it every frame. You can build your time management system so that objects think() every X seconds or X frames or based on some arbitrary priority system instead, or both. With this approach you can have just a few objects think each frame instead of all of them at once. Imagine a cyclic queue where you only do a few eachf frame and the pop them onto the back again.


Thanks a lot. Game Programming Gems is good books.
The solution for my problem is Micro-Threads.
I will try to implement it.

Share this post


Link to post
Share on other sites
Another Game Programming Gems (5 I think) article I read said you could use OpenMP to multithread this type of for loop correctly. I've never used OpenMP so I don't know much about it, but it is worth looking into.

Share this post


Link to post
Share on other sites
Quote:
Original post by Palidine
For your particular example you are trying to parallelize two serial processes which will never work.


I'm with Palidine on this one. If you NEED all objects to be finished thinking before processing them, then all the processors and threads in the world aren't going to speed up your game, since thread/processor B will just be waiting for thread/processor A to finish before doing its thing.

Organizing your code so that tasks can be executed in parallel is the best way to speed up execution. For instance, breaking up the thinking processing makes much more sense than running all the thinking on one thread and then using the results in another thread.

With that said, you'll probably often run into situations where task B depends on task A to finish, in which case you just have to suck it up and deal with the fact that you can't always have everything running at 100% efficiency.

Share this post


Link to post
Share on other sites

for(i=Objects.begin(); i != Objects.end(); ++i)
{
i.Think();
i.thinking = false;
}

In another thread:

list objectList;
for(i=Objects.begin(); i != Objects.end(); ++i)
{
if(!i.thinking)
Report += i.GetResult();
else
objectList.add(i);
}
int x = 0;
while(objectList.count() > 0)
{
if(!objectList.Get(x).thinking)
{
Report += objectList.Get(x).GetResult();
objectList.Remove(x)
}
}
Report.Send();

Share this post


Link to post
Share on other sites

for(i=Objects.begin(); i != Objects.end(); ++i)
{
i.Think();
i.thinking = false;
}

In another thread:

list objectList;
for(i=Objects.begin(); i != Objects.end(); ++i)
{
if(!i.thinking)
Report += i.GetResult();
else
objectList.add(i);
}
int x = 0;
while(objectList.count() > 0)
{
if(!objectList.Get(x).thinking)
{
Report += objectList.Get(x).GetResult();
objectList.Remove(x)
}
}
Report.Send();

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!