theagentd
|
 |
«
Posted
2011-09-18 13:46:17 » |
|
So I got a lot of my programming sorted out recently and managed to get a playable part of my game working. However, I saw horrid performance. Playing around with it for a while, I realized that it "goes away" after a while, doubling my FPS like a flip of a switch. The time it takes for it to start running decently is completely random. Sometimes it's instant, sometime's it's more than a minute, which is obviously unacceptable. First I obviously checked if anything else was running in the background. Nothing. Then I saw that my game's java.exe dances at around 40-45% processor usage during this time, dropping to 25% (100% on one of four cores) when the game starts running as it should. The game doesn't even create a single thread manually, so it should be impossible for it to use 100% on one core (25% in the task manager). I'm basically having a ghost thread draining CPU power in some weird way. I've tried to monitor threads with the profiler in Netbeans, but I can't see any thread stopping or pausing when the lag disappears.
PS: Lol, Minecraft seems to get this too.
|
Myomyomyo.
|
|
|
kappa
|
 |
«
Reply #1 - Posted
2011-09-18 14:56:45 » |
|
You're not by any chance using the sleeping thread trick to fix timing issues on windows? (I do know that minecraft uses this).
|
|
|
|
theagentd
|
 |
«
Reply #2 - Posted
2011-09-18 15:48:52 » |
|
Like I said, I'm not doing anything with threads. I'm gonna try to use that trick now. EDIT: Nope, nothing. Sigh... Just added a very CPU bound feature, and now it doesn't speed up even after waiting minutes. What the heck is doing that?! I've even tried both JDK 6 and 7!
|
Myomyomyo.
|
|
|
Games published by our own members! Check 'em out!
|
|
Conner_
Senior Newbie 
~ Java Game Dev ~
|
 |
«
Reply #3 - Posted
2011-09-18 16:56:12 » |
|
Like I said, I'm not doing anything with threads. Your game isn't doing anything on threads? Or do I misunderstand? Java runs multiple threads in and of itself, and if you aren't organising your program's components into threads, Java will try to run everything on a single thread. That being said, it will probably be really slow, and it will probably eat up CPU.
|
Find me on GitHub: connergdavisMy current project is called Obsidian Framework and is a private Minecraft server application used to play Multiplayer.
|
|
|
theagentd
|
 |
«
Reply #4 - Posted
2011-09-18 17:25:38 » |
|
I'm not creating even a single Thread object, so the fact that another thread slows down my game seems to point to a problem with LWJGL. No problem occurs if I run the exact same code, but without rendering. The scary part is that I can't identify WHICH thread is eating performance.
|
Myomyomyo.
|
|
|
Riven
|
 |
«
Reply #5 - Posted
2011-09-18 17:35:48 » |
|
What happens when you put a sleep(100) in your mainloop?
This might seem like an odd question, but it might be a multi-threaded GPU driver, that will also 'calm down' when you make your game idling.
|
Hi, appreciate more people! Σ ♥ = ¾ Learn how to award medals... and work your way up the social rankings!
|
|
|
loom_weaver
|
 |
«
Reply #6 - Posted
2011-09-18 18:43:55 » |
|
Can you post a reproducer so that we can try it on our systems?
I've been using lwjgl 2.7.1 on Mac Snow Leopard with Java 1.6.0_26 for the last couple of months and haven't had any trouble with lwjgl's performance or rogue processes.
|
|
|
|
Z-Man
|
 |
«
Reply #7 - Posted
2011-09-18 20:01:33 » |
|
You're not by any chance using the sleeping thread trick to fix timing issues on windows? (I do know that minecraft uses this).
Sorry slightly of topic but is this the sleep trick your talking about? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Thread sleeper = new Thread(new Runnable() { public void run() { while(true) try { Thread.sleep(Long.MAX_VALUE); }catch(InterruptedException e) { } } }); sleeper.setDaemon(true); sleeper.start(); |
|
|
|
|
theagentd
|
 |
«
Reply #8 - Posted
2011-09-18 20:41:05 » |
|
FOUND IT! Damn you, Threaded optimization! The problem relates to the setting Threaded optimization in the Nvidia control panel! The ghost thread was a video driver thread! I've actually been experimenting with that setting. The default is Auto, which apparently tries to use multithreading when the game is started and then falls back to single threading when it realizes it gets better performance for less CPU power from that after often less than a second. HOWEVER, if what you're doing is very CPU heavy (i.e. the graphics card is idling a lot) which I was doing it will apparently not fall back as it should. Setting the setting to Off solves this. Thanks to everyone who posted, especially Riven! xD And yes, that is the exact same sleep fix that I used (except I didn't use an infinite loop, fixed xD).
|
Myomyomyo.
|
|
|
kappa
|
 |
«
Reply #9 - Posted
2011-09-18 21:07:02 » |
|
Sorry slightly of topic but is this the sleep trick your talking about?
Yup, that's the one (or a variation of it).
|
|
|
|
Games published by our own members! Check 'em out!
|
|
Z-Man
|
 |
«
Reply #10 - Posted
2011-09-18 22:36:42 » |
|
Sorry slightly of topic but is this the sleep trick your talking about?
Yup, that's the one (or a variation of it). Cool... so is it only needed on Windows? Does it really help if you have it running on Mac or Linux?
|
|
|
|
gimbal
|
 |
«
Reply #11 - Posted
2011-09-19 09:23:27 » |
|
It won't help, its a Windows specific fix in the JVM. As long as a thread is asleep the JVM keeps the resolution at 1ms to make waking up threads/locks/timers more precise. As soon as there is no sleeping thread the resolution is reset to the default 10 or 15ms (system dependent, happy happy joy joy).
Because the precision is already high enough (1-2ms) on Linux or Mac platforms out of the box, the JVM for those platforms does not have the workaround and so the sleeping thread trick adds nothing.
|
|
|
|
ra4king
|
 |
«
Reply #12 - Posted
2011-09-20 00:08:47 » |
|
So basically: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| if(System.getProperty("os.name").startsWith("Win")) { new Thread() { { setDaemon(true); start(); } public void run() { while(true) try{ Thread.sleep(Long.MAX_VALUE); } catch(Exception exc) {} } } } |
|
|
|
|
princec
|
 |
«
Reply #13 - Posted
2011-09-20 10:15:47 » |
|
Hm we should probably just build this in to LWJGL. Cas 
|
|
|
|
gimbal
|
 |
«
Reply #14 - Posted
2011-09-20 13:39:08 » |
|
Hm we should probably just build this in to LWJGL. Cas  As apposed to the JVM itself, yes. Sun already attempted that once with a command line switch, but they managed to fail in a very epic way: http://bugs.sun.com/view_bug.do?bug_id=6435126Note that the sleeping thread hack fix is actually mentioned as a workaround to this bug!
|
|
|
|
delt0r
|
 |
«
Reply #15 - Posted
2011-09-20 14:09:50 » |
|
Why is it needed? what does it fix?
|
I have no special talents. I am only passionately curious.--Albert Einstein
|
|
|
kappa
|
 |
«
Reply #16 - Posted
2011-09-20 14:23:42 » |
|
As apposed to the JVM itself, yes. Sun already attempted that once with a command line switch, but they managed to fail in a very epic way:
Wow, that is epic fail indeed. Whats even worse is that they want to keep the broken switch in there.
|
|
|
|
ra4king
|
 |
«
Reply #17 - Posted
2011-09-20 22:29:41 » |
|
Why is it needed? what does it fix?
In Windows, the default resolution of the timer is about 10 ms. This trick forces the JVM to use the High Resolution timer for more accurate sleeping.
|
|
|
|
gimbal
|
 |
«
Reply #18 - Posted
2011-09-22 10:49:50 » |
|
As apposed to the JVM itself, yes. Sun already attempted that once with a command line switch, but they managed to fail in a very epic way:
Wow, that is epic fail indeed. Whats even worse is that they want to keep the broken switch in there. Wanted. Sun is gone, Oracle is now in charge. Seeing what the last dozen updates to Java 6 have brought, it is clear that Oracle is more inclined to apply fixes that break backwards compatibility. What I don't like is that they often do so silently :/
|
|
|
|
|