Is tight looping bad? - java

Is tight looping in a program bad?
I have an application that has two threads for a game-physics simulator. An updateGame thread and a render thread. The render thread is throttled by causing the thread to sleep for some milliseconds (to achieve the frame-rate I want) and the updateGame thread (that updates my in game objects positions based off some physics equations) was previously throttled by a 10 millisecond sleep.
However, I recently unthrottled the updateGame thread and the simulation of my objects movement seems to be significantly more realistic now that I have taken out that 10ms sleep. Is it bad to hot loop or have a tight loop?
private class UpdateTask implements Runnable
{
private long previousTime = System.currentTimeMillis();
private long currentTime = previousTime;
private long elapsedTime;
public void run()
{
while(true)
{
currentTime = System.currentTimeMillis();
elapsedTime = (currentTime - previousTime); // elapsed time in seconds
updateGame(elapsedTime / 1000f);
try {
Thread.currentThread().sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
previousTime = currentTime;
}
}
}
In this example I'm just sleeping for 1ms (and from my understanding with how millisecond accuracy and the sleep function works this is probably more like 5-10ms. If I sleep for any more than this it starts to have impacts on the accuracy of my collision detection and physics model.
Is it a bad practice to have tight loops or loops with 1ms sleeps in them? Is there something else I should do instead?

I read a really great post about efficiently and effectively executing physics calculations loop: Fix Your Timestep!
When a game is running that is usually the main application that the user cares about so tight looping is not that big of a deal. What you really should do though schedule your updates. You should know how long -- at your target framerate -- that your frame has to execute. You should measure the time that your frame took and only sleep for the time that your frame took minus that known frame time. That way your system will lock into a frame rate and not vary with the amount of time that your frame takes to render.
Another thing is that I don't believe that Thread.sleep has a very good resolution, well over 5 milliseconds, you may want to look for a more accurate timer available for Java.

It's only "bad" if it has an adverse impact on something else in your system. Rather than sleeping for 1ms, you might block on a condition that warrants updating, with a minimum of 1ms. That way you'll always sleep for at least 1ms, and longer if there's nothing to do.

As Adam has pointed out in his answer, there may be an adverse impact on the performance of the system.
I've also tried making games in a very similar manner (having a rendering and motion calculations on separate threads) and I have found that not having the Thread.sleep will cause the Java application to take a very significant portion of the CPU time.
Another thing to consider is that the system timer itself. As you've mentioned, although the Thread.sleep method is takes in the number of milliseconds to sleep, but that precision is dependent (as noted in the API specifications) on the timer provided by the operating system. In the case of Windows NT-based operating systems, the timer resolution is 10 milliseconds. (See also: System.currentTimeMillis vs System.nanoTime)
Yes, it is true that having the Thread.sleep has the potential to decrease the performance of your application, but not having that can cause the system utilization by the application to skyrocket.
I would guess the decision comes down to whether the application should take up a significant portion of the system utilization, or to act nice and share the CPU time with the other applications running on the system.

Also consider laptop users, running a tight loop continuously will keep the CPU running hard, and this will chew through their battery (many flash games are guilty of this). Something to consider when deciding whether to throttle your loops or not.

The answer by joshperry is pretty much what you want, but there are also a few ways about it. If you are using multiple threads, you have to also deal with locking etc. Depending on your game architecture that may / may not be a big deal. For example, do you do lots of locking, is there a lot of message passing between threads etc. If you are a traditional game you usually have a single main loop - I have a queue of CMD objects (runnable if you like, but can also be more event bus like in nature) that are executed continuously until the queue is empty. The thread then waits until it is signaled that a new cmd is in the queue. For most games this is usually enough. So the question then becomes how / when are cmds added. I use a timer/scheduler (also note the comments about java time resolution) to add a cmd to the main loop at the required frame rate. This has the advantage of also being kind to laptops etc. On startup you can also then benchmark the system to see how fast it is running, and then set an appropriate frame rate (ie. start with a supported base, then work to a max). Benchmarking or using user specified performance hints (ie. amount of rendering detail) can then be used by each type of cmd (ie. the render scence cmd / event looks at the performance settings for detail etc). (note - cmds dont' have to be runnable, they can be more like an event bus with listeners that are invoked on the main thread).
Also if a task wants to then use multi-thread/core's the handler for the cmd (if its an event type model - i personally like the event model - its easier to access the shared state info without needing global singletons) can then spawn multiple tasks (say using an existing thread pool - so the cost of new threads are not hit every cmd) and then use a barrier type class to wait for all the tasks to complete. This method usually makes locking easier, as each cmd (or system) usually has different locking requirements. Thus you can implement just the locking for that system and not have to worry about locking between sub systems - ie. for physics you can lock on bundles of objects in the game area, and each forked thread in the thread pool then worries only about its objects ie. thread1 handles objects1 to 20, thread2 objects 21-40 etc (this is just to illustrate the concept of how each cmd can implement a custom locking algorithm that works best for what it is doing, without having to worry about what other sub systems are doing with shared state data).
The important thing is to look at how and why you are using threads and locking etc.

For a game, probably not. Just make sure your game pauses when the switches tasks.

You would actually want to use Thread.yield() in this case. It is possible that one thread will run continuously, and not allow any other threads time to execute. Placing a yield call at the end of each iteration gives the scheduler a hint that it is time to allow other threads to run as well.

Related

while loop or Thread.sleep()?

I'm programming a game in Java and I limit the FPS to 60. I figured out 2 different ways to get the same result, but I'm wondering which of them is the better/cleaner way to do it. Or maybe you have a different idea.
while(System.nanoTime() - thisFrame < fps_limit);
or
Thread.sleep(sleepingTime);
My thinking is that the while loop effects the CPU more than Thread.sleep, am I right?
Thanks in advance for your help!
Dom
You have the following main options:
While loop - This will consume CPU cycles and often will actually stop the system because while you are looping, other threads cannot run (on a one-core machine).
Thread.sleep() - This can be effective but you need to remember that is not guaranteed to wait the specified time.
DelayQueue - More up-to-date. Better/accurate timing.
ScheduledThreadPoolExecutor - Still more up-to-date than DelayQueue. Uses a Thread Pool.
You're right, while both with achieve what you're trying to do, the while loop will keep the processor occupied, consuming CPU time.
In contrast, Thread.sleep() frees the processor for the amount of time mentioned.
So, Thread.sleep() is better.
Both the answers posted already are good - sleep is better than loop. However, you can go into much more detail about how to write a good loop. If you are interested, here is a great resource: http://www.java-gaming.org/index.php?topic=24220.0
It covers topics like variable timestep and interpolation, which can be used to make your graphics run extremely smoothly. This solves the issues Thread.sleep has with not being 100% accurate in its timing as well as preventing your graphics from appearing jerky if your game performs some calculation that takes some time.
What I would do (pseudo code).
//timepast since last loop in ms
timepast = 0
fpslimit = 60
finished = true;
//while the game is running
while(runnning)
{
timepast += timeSinceLastrun
if(timepast > 1second/fpslimit && finished)
{
finished = false
dostuff(timepast)
}
//sleep for the time of 1second/fpslimit - timepassed to avoid cpu blocking
Thread.sleep((1second/fpslimit) - timepast )
}
dostuff(deltatime)
{
//do stuff in the end after it finished set
//finished to true so dostuff can be called again
finished = true
timepast=0
}
In this way you can easily limit the fps with a variable and dont need to block other threads.
as OldCurmudgeon said thread.sleep dosnt block other threads in java and make processor time available.
Thread.sleep causes the current thread to suspend execution for a
specified period. This is an efficient means of making processor time
available to the other threads of an application or other applications
that might be running on a computer system
Also you can pass timepast to the dostuff method as a deltatime so the game runs the same on all devices (same speed).
I concur with #ayush - while loops are usually blocking functions, whereas threads are more like interrupt-driven or parallel programming functions. I'm a bit green on Java, but could you not setup a timer rather than sleeping?
Yeah it looks like Timer constructs, like in C++, are available. Check this out: Timer in Java Thread
You should use neither of them. Please take a look at the documentation for ScheduledThreadPoolExecutor
In particular you are looking at this function
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long initialDelay, long period, TimeUnit unit)
while loop will use CPU resource and it is good only if your avg.waiting time is very less and expecting precision.
Thread.sleep() is fine if no precision is expected as CPU priority will change after thread wakes up and it may or may not be scheduled immediately to run and it also should not to be used like this
while(! canContinue()) {
Thread.sleep(1000);
}
For the above case, alternative is these cases better to use wait()/notify() if you want to suspend the current thread and wait for another thread to process something and then notify the current thread to continue.
some references you can read,
http://tutorials.jenkov.com/java-concurrency/thread-signaling.html
http://www.jsresources.org/faq_performance.html#thread_sleep

Minimum time to sleep to ensure sleep occures regardless of clock cycle?

I know clock cycles vary between operating systems and settings. If I am writing code that wants to be relatively confident (at least 95% sure) of a sleep occurring what is the minimum time I could use for a sleep and be confident that any computer/os running the code will sleep?
Is there a way to gaurente a sleep of at least one 'clock cycle' regardless of how long that cycle is in java?
You should never try doing that. Ask yourself if you really need to sleep for one clock cycle. Tying your implementation with timers is always a bad decision. Below I give you a few alternatives.
Use a mechanism similar to fps in games implementation
A number of libs already implement the concept of fps. Usually their implementation already abstract away clocks per second and OSes limitations/details. You could use that concept and be platform agnostic.
This way you can tweak your time requirement by using more or less fps.
Use a mutex.
Why do you need to sleep for one cycle? That is a very small amount of time. You could try to synchronize (if that is the case) using mutexes instead of timers.
Also, mutexes are usually implemented by hardware instructions. So that guarantees they are atomic. If you really need to sleep for an infinitesimal time, you could lock the mutex and then unlock it. To be honest, any code you execute will by definition (unless it is a NOOP) be similar to sleeping by one cycle. You could also use tmp = 1+1. That takes two instructions.
I suggest the mutex. From your question, it is not clear why you need that sleep time.
Mutex with user interaction
If you need to wait for user interaction (or any external event, like requests), lock the mutex and only unlock it when the event or user input becomes available.
Derive the timer value
If you really wanna go down the timer road, I suggest you implement a routine that executes a long for loop and then you can try to derive your timer from the time it took to run through that for loop.
As I said earlier, I don't find this approach to be reliable but it is something. Also, I suggest that you also protect this code using a mix of Monte Carlo reliability techniques and unit tests. You can read more about this on this article.
As a final note, beware the optimizations that the compiler/interpreter can make and screw your timer.

Is there a danger in having a high number (20+) of simple threads?

I am writing a game in Java. I have in-game tutorials. Each tutorial is essentially a 5-10 frame animation that changes every second.
For each tutorial, I have a simple thread running:
int sleepTimeMillis = 1000;
public static void run() {
while ( true ) {
try {
tutorialFrame = ( tutorialFrame + 1 ) % numberOfFrames;
Thread.sleep ( sleepTimeMillis );
catch ( InterruptedException e ) {}
}
}
I currently have about 10 of these running. By the time I finish all of them, I imagine I'll have about 50.
Otherwise, my game uses a handful of threads: One for the windowing environment, one for the game logic, one for the rendering engine, and probably a handful of other small ones here and there.
Unsurprisingly, I haven't noticed any speed issues in the game by adding these threads. That being said, I'm not knowledgeable on the behind-the-scenes overhead for having many threads within a process.
I could restructure the program in a different way if it is desirable to reduce the number of these tutorial threads.
So I'm asking whether it's worth the time to re-structure the tutorials a little so they all share one thread, or whether it makes sense to just leave things how they are.
Thanks!
Threads are tricky. The first time people learn threads concept, they think: "Awesome, now I can run everything in parallel! I will use threads as much as possible everywhere!". But there are pitfalls. Let's start from the CPU, that has multiple cores. To a first approximation, the number of threads which can be run simultaneously is equal to the number of cores (detailed comments on that, like hyperthreading, are welcome). So, if you created 100 threads, only 4 can be executed simultaneously on a machine with 4 cores. And there is a thread scheduler, which schedules threads for execution.
The process when thread scheduler gives CPU time from one thread to another is called context switch and it takes some time. Moreover, when you create a new thread you allocate some memory for its stack. Considering that, having many (let's say 50) threads is bad because:
you are using extra memory. On a x64 machine default thread stack size is 1MB. 50 threads = 50 MB.
context switch happens too frequently, you are loosing time on that.
You'll end up with having many threads, that most of the time do nothing, just wasting resources. So, what's the solution? Instead of creating new threads each time you need to execute some task asynchronously, you can use ExecutorService, there is a nice article on that. Also, looking at your code, it looks like you are executing recurrent task. If so, you can use Timer class, just create TimerTask and schedule it at fixed rate.
It is more efficient to have your tutorial as sprites and use the Sprites Update and draw methods. That way you are only using the one thread to update everything. Having more then one thread do the work is a waste.

Make something wait without using Thread.sleep()?

I am trying to make an intro to a game with some strings that I want one to wait for another to pop up, and I don't directly want to use Thread.sleep() for it to wait, because I am not sure if that is the best option. Is there any other way to make something wait than making the thread sleep, or will I just have to make the thread sleep?
If this is a game you shouldn't use sleeps or timers.
Typically games have their own internal clock mechanism. This means you will try to render the frames as fast as possible. Your OnRender method will be invoked with the current time of the game. You can use this to determine if enough time has passed to go to the next screen.
This means you will be given a point in time A in frame 1. You'll be given the Delta or another point in time B in frame 2. You can determine how much time has passed by using the delta or calculating the delta yourself. This is a very efficient mechanism for timing situations and worked quite well when games were single threaded. The idea of any program is to never block for anything.
The reasons things typically block is due to I/O such as reading from disk, the network or putting data on the GPU. In your situation you can do everything without blocking.
Here is a decent page on this https://gamedev.stackexchange.com/questions/1589/fixed-time-step-vs-variable-time-step
There's a standard mechanism for this: Object.wait() and Object.notify() (with their overloads / variants). You simply wait for some event to occur in one thread, and some other thread is responsible for notifying you (or everyone, in case of notifyAll) of that occurrence.
You can also make use of the new Condition mechanism introduced in java.util.concurrent.
If you're making this in a game, why not try using something like Actions in libgdx? You just chain different actors together. Whenever a property like visibility or position reaches the value you want, you trigger the next action. Properties conditions are checked during each update loop of your game.
Or if its a swing app, use a timer to check these properties.
long t1=0,t2=0;
long nanoWaitTime=10000; //to wait at least 10000 nano-seconds
t1=System.nanoTime();
//start waiting
long count=0;
boolean releaseCpuResources=true;
while(Math.abs(t2-t1)<nanoWaitTime)
{
t2=System.nanoTime(); //needs maybe 1000 cycles of cpu to get this value.
//so this is like busy-wait
//and minimum step may be 1 micro-seconds or more
if(releaseCpuResources)
{
count++;
if(count>1000)Thread.sleep(1);//after too many iterations, cpu gets overwhelmed
//so Thread.sleep makes it better for large waiting
//times
//but precision is lost. Like uncertainity principle
//but in a quantized fashion
}
}
// here continue to work after waiting
The resolution or precision may not be what you want in for all cpus.

Thread.sleep() VS Executor.scheduleWithFixedDelay()

Goal: Execute certain code every once in a while.
Question: In terms of performance, is there a significant difference between:
while(true) {
execute();
Thread.sleep(10 * 1000);
}
and
executor.scheduleWithFixedDelay(runnableWithoutSleep, 0, 10, TimeUnit.SECONDS);
?
Of course, the latter option is more kosher. Yet, I would like to know whether I should embark on an adventure called "Spend a few days refactoring legacy code to say goodbye to Thread.sleep()".
Update:
This code runs in super/mega/hyper high-load environment.
You're dealing with sleep times termed in tens of seconds. The possible savings by changing your sleep option here is likely nanoseconds or microseconds.
I'd prefer the latter style every time, but if you have the former and it's going to cost you a lot to change it, "improving performance" isn't a particularly good justification.
EDIT re: 8000 threads
8000 threads is an awful lot; I might move to the scheduled executor just so that you can control the amount of load put on your system. Your point about varying wakeup times is something to be aware of, although I would argue that the bigger risk is a stampede of threads all sleeping and then waking in close succession and competing for all the system resources.
I would spend the time to throw these all in a fixed thread pool scheduled executor. Only have as many running concurrently as you have available of the most limited resource (for example, # cores, or # IO paths) plus a few to pick up any slop. This will give you good throughput at the expense of latency.
With the Thread.sleep() method it will be very hard to control what is going on, and you will likely lose out on both throughput and latency.
If you need more detailed advice, you'll probably have to describe what you're trying to do in more detail.
Since you haven't mentioned the Java version, so, things might change.
As I recall from the source code of Java, the prime difference that comes is the way things are written internally.
For Sun Java 1.6 if you use the second approach the native code also brings in the wait and notify calls to the system. So, in a way more thread efficient and CPU friendly.
But then again you loose the control and it becomes more unpredictable for your code - consider you want to sleep for 10 seconds.
So, if you want more predictability - surely you can go with option 1.
Also, on a side note, in the legacy systems when you encounter things like this - 80% chances there are now better ways of doing it- but the magic numbers are there for a reason(the rest 20%) so, change it at own risk :)
There are different scenarios,
The Timer creates a queue of tasks that is continually updated. When the Timer is done, it may not be garbage collected immediately. So creating more Timers only adds more objects onto the heap. Thread.sleep() only pauses the thread, so memory overhead would be extremely low
Timer/TimerTask also takes into account the execution time of your task, so it will be a bit more accurate. And it deals better with multithreading issues (such as avoiding deadlocks etc.).
If you thread get exception and gets killed, that is a problem. But TimerTask will take care of it. It will run irrespective of failure in previous run
The advantage of TimerTask is that it expresses your intention much better (i.e. code readability), and it already has the cancel() feature implemented.
Reference is taken from here
You said you are running in a "mega... high-load environment" so if I understand you correctly you have many such threads simultaneously sleeping like your code example. It takes less CPU time to reuse a thread than to kill and create a new one, and the refactoring may allow you to reuse threads.
You can create a thread pool by using a ScheduledThreadPoolExecutor with a corePoolSize greater than 1. Then when you call scheduleWithFixedDelay on that thread pool, if a thread is available it will be reused.
This change may reduce CPU utilization as threads are being reused rather than destroyed and created, but the degree of reduction will depend on the tasks they're doing, the number of threads in the pool, etc. Memory usage will also go down if some of the tasks overlap since there will be less threads sitting idle at once.

Categories