Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (499)
Games in Android Showcase (118)
games submitted by our members
Games in WIP (568)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  Render/Update Threads  (Read 6754 times)
0 Members and 1 Guest are viewing this topic.
Offline sophka

Innocent Bystander




Java games rock!


« Posted 2004-11-30 00:42:17 »

Hi everyone,
im wondering if anyone ever coded a game using two separate threads for updating and rendering, in order to make sure that the updating happens at fixed intervals no matter how slow the rendering (that way players in a multiplayer game stay in sync).
Ive been using wait/notify mechanism with java, but i got very poor performance, so any suggestion/comment/idea would be highly appreciated.
Thx  Wink!
Offline Seb

Senior Newbie




import com.acme.Bomb;


« Reply #1 - Posted 2004-11-30 17:02:32 »

Perhaps you could just skip rendering some frames in a single threaded update/render loop when it would cause too much of a delay.

This of course wouldn't look too nice as skipping frames might be noticeable by the user sometimes, but it's an idea.

Seb

Offline tom
« Reply #2 - Posted 2004-11-30 21:53:22 »

Do NOT use two separate threads updating and rendering the same game state. You can not render when state is updateing and vica versa. If you update at fixed intervals as you suggest you will get synchroinzation bugs. This is if they share data. The rendering thread can get a copy of the game state before rendering. Then you only have to syncronize the cloning of the state. I hope this is what your doing.

In a multiplayer game it might be a good idee having a separate thread for the server logic. Let the local player get it's state from the server the same way as the other clients, threw a socket.

Have to know more about what your doing to find you why your getting poor performance. It's probably a design isue.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Vorax

Senior Member


Projects: 1


System shutting down in 5..4..3...


« Reply #3 - Posted 2005-01-07 10:17:20 »

Quote
Do NOT use two separate threads updating and rendering the same game state. You can not render when state is updateing and vica versa. If you update at fixed intervals as you suggest you will get synchroinzation bugs. This is if they share data. The rendering thread can get a copy of the game state before rendering. Then you only have to syncronize the cloning of the state. I hope this is what your doing.



Umm..I have to disagree with this.  This is the best way to do things if you can manage it properly.

Rendering should be just that, rendering.  A clean seperation of game and renderer is the best approach to performance.  

Though you are right it does mean you need to do some synchronization, but its not difficult or error proned as long as you have the seperation between renderer and game state as a goal of your engine.  

Most people think thread synchronization means wasted cycles...and it does...but with multi-processors (CPU/GPU) you end up with very little becuase you gain more performance from keeping them both busy then you loose when the odd time one has to wait for the other occurs.

If done correctly you will have your engine running at a constant (or at least close) speed and your renderer running also as fast as it can.

The general rule of performance in games is pretty simple keep both the GPU and the CPU busy at all times and this can only be done by seperating game state from renderer.

Basically: While the GPU is rendering the last frame, your other thread is updating the game objects/state in preperation for the next frame.   This approach does use more memory of course, because you have doubled your geometry for non-static entities (static geometry and attirbutes should be shared between engine and renderer for things like preconditioned collision detection...a collision calc on a wall can be done while the wall geometry is being read by the renderer)

Networking a game is also MUCH easier if the renderer and the state are in seperate threads.

You end up with two FPS counts:
Rendering FPS and Engine FPS.

Renderer FPS fluctuates with pipe-line saturation
Engine FPS fluctuates very little (depending on complexity or things like poorly implementing the networking side)




Offline princec

JGO Kernel


Medals: 391
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #4 - Posted 2005-01-07 13:39:24 »

Actually we have to disagree with you here Vorax, and your reasoning is actually based on a misunderstanding of how the GPU works.

It is absolutely, strongly advised to do rendering and "ticking" in one single thread, mainly because synchronization cannot be accurately or reliably scheduled and it's hard to do.

Secondly, there is already a separate rendering thread going on, except it exists in the GPU and AGP bus, not on the CPU, and Java doesn't know anything about it.

Your ticking thread may be thinking about a bunch of stuff but the reality is that while it's thinking, the GPU is sucking data down the AGP bus and drawing it in the background. When you're done thinking, swap buffers, and start rendering immediately. Rendering should consist solely of blatting data down to OpenGL (or whatever).

This way you are pretty much guaranteed to get maximal performance, minimal complexity, and great results.

Cas Smiley

Offline Raghar

Junior Member




Ue ni taete 'ru hitomi ni kono mi wa dou utsuru


« Reply #5 - Posted 2005-01-07 18:24:01 »

What type of updating and what type of rendering thread do you mean? If you mean a game engine interaction with a graphic engine, then game engine, or better to say world engine should be asymetrical thus update of rendered data should be assymetrical and lazy as well.

Of course every one knows how graphic card works. Half of the image data is pushed into the memory, then transfered by AGP to the GFX. GFX would store them in it's fast memory (hopefully) and uses them for various transformations. In the mean time second GFX card uses second half of the image data. Then rasterizer comes and everything is encoded into some TV like channel that is decoded on the monitor into the binary data and showed in a 18 bit colors. If you doesn't have the right resolution, or right monitor you are screwed.
Letting rasterizer work faster than 75 FPS is pointless, forcing input polling 200 UPS isn't.
And if you think this is horrible, then just wait what would do your graphic engine to reflections.

My current GFX doesn't know much about threads, and I hope NVIDIA will not be stupid and rather increase amount of pipelines, and FP consistency. It's however pretty much usable as a secondary processor.  

A little warning I listened that at least some ATI cards are pretty bad in sending data into main memory. Writting to AGP was 3x faster than reading from AGP. Nasty.

Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #6 - Posted 2005-01-07 20:22:16 »

Quote
Writting to AGP was 3x faster than reading from AGP. Nasty.



Isn't this generally the case with all cards, on purpose? AGP is designed to send data one way only, pretty much. glReadPixels sucks for this reason. PCI-X, on the other hand...

malloc will be first against the wall when the revolution comes...
Offline Vorax

Senior Member


Projects: 1


System shutting down in 5..4..3...


« Reply #7 - Posted 2005-01-08 02:17:02 »

Quote
Actually we have to disagree with you here Vorax, and your reasoning is actually based on a misunderstanding of how the GPU works.


No, I don't think I misunderstand, I just think I understand threading very well. Wink

For things like collision detection, particle engines, AI, in memory texture generation outside of OGL, on-demand loading and complex geometric deformation, etc, you can get much improved peformance if you thread the effort and seperate it from the rendering loop.

But for further evidence:

Multi-threading in Games (Game Developers Conference 2004)
"Perimeter

Perimeter is a real-time strategy game being developed by the Russian studio KD Labs. RTS games are necessarily CPU-heavy. Perimeter implements constant terrain reforming as a gameplay element, and also incorporates highly detailed graphics for an RTS game. The dev team broke up the main loop into two threads, one for the user interface and graphics rendering, the other for logic and AI.

The net result was a substantial increase in performance. In a demo of the game with multithreading disabled, the game exhibited a frame rate hovering in the 12-18 fps range, while the multithreaded version ran at 22-30fps on debug code on a 3.2GHz Pentium 4.

See for more info:

http://www.extremetech.com/article2/0,1558,1554199,00.asp


Quote
It is absolutely, strongly advised to do rendering and "ticking" in one single thread, mainly because synchronization cannot be accurately or reliably scheduled and it's hard to do.


Synchronization can be very easily predicted if you can profile your code well enough.  Generally, if you have complex geometry, the GL calls and buffer swap will be your codes biggest lag.  If you can do all the other stuff in another thread before that completes (without starving the GL calls for more time then your refresh rate...usually not hard to do if your engine implemented a good PVS or octree, frustum culling, occulsion, etc...if not, the user would notice the FPS drop anyways), then synchronization is just for cases where your CPU got lagged, which would have slowed down your main loop anyways.  Even if you can't you might have got a good chunk of it done in the other thread.  

Quote

Secondly, there is already a separate rendering thread going on, except it exists in the GPU and AGP bus, not on the CPU, and Java doesn't know anything about it.

Your ticking thread may be thinking about a bunch of stuff but the reality is that while it's thinking, the GPU is sucking data down the AGP bus and drawing it in the background. When you're done thinking, swap buffers, and start rendering immediately. Rendering should consist solely of blatting data down to OpenGL (or whatever).


But what about the overhead of the actual render calls?  What about the buffer swap itself?  All lengthy operations involving alot of bus waste.  What about the waste of your engine itself?...

John Sweeney Raven Games (Technical lead of SOF2)
"Obviously waiting for Vsync before window swapping can cause a slow down. If you take 1.1 frames to draw a scene, then wait for Vsync before swapping frame buffers that means that .9 of that frame is spent doing nothing on the card. The OpenGL context can accept commands and buffer them up, but it's not going to be doing any rendering until the buffers are swapped and the back buffer is unlocked for rendering again. You can see why this would slow the game down."

You can disable Vsync, but now you are doing overdrawing when you can render faster then the monitor will display it.

A better solution is don't waste the GPU's time or the CPU's time.  With threads you can balance your processing for both parts.  Lets say the refresh rate is 85Mhz, the optimal solution is to have your rendering loop doing no more then that when issuing to the front buffer.   Once you have achieved that, you have spare cycles for the engine to use for things like AI..etc.  You can let buffer wait's handle that for you, but not accurately unless you can predetermine how long the next frame will take to actually be rendered.  With a second thread you don't need to concern yourself with vsync on or off.  The goal being to have your engine  function at it's own rate.  

Behaviors in Java 3D are a good example of this effect and usefulness.  You can start off using nothing but Frame notification to do things like prediciton/collision, but as the game gets more complex you will see a drop in your FPS.  Behaviors can elivate this to a degree becuase they are a seperate thread and can allow you some independence of the graphics rendering entirely.  Switch from frame notification to a timed notification and you will get better overall CPU/GPU utilization. (though I don't condone the exceisive synchronization in J3D, a little to generic, but it is effective for many uses where the CPU is getting a work out along with the GPU).

The final advantage is what I think the original poster was going for.  Your game operates consistently despite the capabilities of the bus and GPU (lets also not forget a big hurdle for java is also the JNI overhead from the JOGL calls).  Varying system capabilities are big issues for games like Doom 3 and HL2 where they are tyring to support a very broad range of hardware capabilities, but keep the game play fair for all.  In a single threaded engine you are very limited in what you can do.  For example you can adjust the player movment based on lag calculations inccured by network or FPS...standard stuff...but that is actually about as much as most people do because the complexity increases greatly when dealing with other parts of the game:  what about lost time for AI?  What about particle accuracy?  What about physics accuracy?  Those things tend to be very difficult to base off a lag timer.  Its much better to keep the game engine at a constant frame rate (I mean frame rate like Carmack means engine frame rates, not graphics frame rates) and do all work based on that thread.  Let the graphics/network lag come as it will, but keep the player in the same world as everyone else.  That way graphics hardware and network speed become much less of an issue (though network threading to a much smaller degree..whole other can of worms...best solved with threads Wink ).

Of course, I may not know what I am talking about (my knowledge is greatly based off of others)....but it is working for me.  

In the game I am working on, I track two FPS rates, engine and renderer.  Renderer varies from 52 FPS at worst (12 live entities (1200-1500 tri each), 24 active particle systems with around 200 quad particles per system), 12 animation trackers (run-time generated key frame splines), collision detection (AI is really just random at this stage)...up to 410 FPS when staring at nothing.  

With 410 fps at nothing, but still calculating everything in the engine (this will be greatly optimized with entity activity bounds later), that means the wait incurred by the calculations/synchronizations is costing me around 1-2ms (measured), while hard geometry rendering costs around 16ms...so I have a surplus 3-4ms for additional calculation before the target worst case of 50FPS rendering is reached (unoptimized), which means i can use all that power for the unimplemented AI.  Once I attack the geometry with a stripifer, I should be able to almost double the current renderer FPS rate (all triangles/quads atm), which will mean I get a final net of 90-100fps or so...or an additional 8-10ms for per frame processing.  Though, I will be adding more geometry to the game, so I am only anticipating around another 4-5ms beyond my current.

The engineFPS ranges from 55-60 no matter what is going on, to maintain this I must not exceed my anticipated excess of 4-5ms).  The computer this is tested on is a modest 1.8 Ghz machine, with a Geoforce 4MX (better to test on crap as they say).

I have been working on this game for about two months now and spent 3 months researching the design of the engine before starting it...I guess you'll have to wait for the results before you can determine if I am smoking something or not Wink

PS:  Anyone know of a good java stripifier?

Offline kevglass

JGO Kernel


Medals: 172
Projects: 23
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #8 - Posted 2005-01-08 08:15:48 »

Java3D is known for being slower than other solutions. Again from the knowledge of others I've been informed this has alot to do with their use of synchronisation. Hence people like Xith didn't bother and got way better performance.

Quote

In the game I am working on, I track two FPS rates, engine and renderer.  Renderer varies from 52 FPS at worst (12 live entities (1200-1500 tri each), 24 active particle systems with around 200 quad particles per system), 12 animation trackers (run-time generated key frame splines), collision detection (AI is really just random at this stage)...up to 410 FPS when staring at nothing.    


This being an increadibly trivial engine test I don't think its really relevant.

Like you I can't talk for industry experience but I have tried lots of different ways of writing games in Java over the last 3 years. I've certainly come down on the side that one thread is better (at least where logic/rendering are concerned - networking is still up for debate in my mind).

Kev

Offline princec

JGO Kernel


Medals: 391
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #9 - Posted 2005-01-08 12:35:22 »

I talk from experience now Smiley

Don't use threads! And I can say no more on the subject because it has been said many times before.

<edit>Except for networking! Where they are absolutely 100% ideal.

Cas Smiley

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline kevglass

JGO Kernel


Medals: 172
Projects: 23
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #10 - Posted 2005-01-08 14:09:17 »

Re: Networking , I've been back and forward on the issue. I think theres a difference between accepting network traffic and applying it to the data model. A seperate thread for accepting and storing the network updates makes sense. Actually applying the changes seems to be nicer in the main thread (i.e. as part of game logic).

Just the feeling for me so far..

Kev

Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #11 - Posted 2005-01-08 14:35:29 »

Quote

No, I don't think I misunderstand, I just think I understand threading very well. Wink
...

But for further evidence:

Multi-threading in Games (Game Developers Conference 2004)
"Perimeter

...The dev team broke up the main loop into two threads, one for the user interface and graphics rendering, the other for logic and AI.

The net result was a substantial increase in performance. In a demo of the game with multithreading disabled, the game exhibited a frame rate hovering in the 12-18 fps range, while the multithreaded version ran at 22-30fps on debug code on a 3.2GHz Pentium 4.


That's not "evidence". That merely says their coders are poor or alternatively a lot about how self-fellating their promotional speakers are. GDC talks aren't selected for quality and accuracy so much as for "fame" and "contentiousness" and "interest" of what is going to be said.

Quote

John Sweeney Raven Games (Technical lead of SOF2)
"Obviously waiting for Vsync before window swapping can cause a slow down. If you take 1.1 frames to draw a scene, then wait for Vsync before swapping frame buffers that means that .9 of that frame is spent doing nothing on the card. The OpenGL context can accept commands and buffer them up, but it's not going to be doing any rendering until the buffers are swapped and the back buffer is unlocked for rendering again. You can see why this would slow the game down."


Not really single versus multi-threading, this is instead a discussion of "how to workaround bugs in the API design where you are only provided with blocking calls".

It is a base assumption of writing a single-threaded game that all your calls which can be are asynchronous and predictable. If you have that, there's no advantage to using threads. In theory, you ought to have that available. In practice, lots of things annoyingly aren't feature-rich enough.

e.g. from a developer perspective I have no need to block on waiting for a vsync, I should instead be able to check how long I've got until the next vsync happens. Much much more useful.

malloc will be first against the wall when the revolution comes...
Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #12 - Posted 2005-01-08 14:47:02 »

Quote
Re: Networking , I've been back and forward on the issue. I think theres a difference between accepting network traffic and applying it to the data model. A seperate thread for accepting and storing the network updates makes sense. Actually applying the changes seems to be nicer in the main thread (i.e. as part of game logic).

Kev


- when you get to "check network stuff" part of main loop, you just query your non-blocking channels
- ...process it...
- re-loop

What's the problem? Why bother with mutliple threads? Your game-loop is running at least 60 times a second, so ... the additional latency of the delay until the networking is processed is noticeably less than the ping time to the server.

malloc will be first against the wall when the revolution comes...
Offline princec

JGO Kernel


Medals: 391
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #13 - Posted 2005-01-08 15:04:16 »

Ah sorry, I was thinking serverside when I mentioned threads & networking together in the same sentence.

Cas Smiley

Offline kevglass

JGO Kernel


Medals: 172
Projects: 23
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #14 - Posted 2005-01-08 15:13:54 »

Quote

What's the problem? Why bother with mutliple threads? Your game-loop is running at least 60 times a second, so ... the additional latency of the delay until the networking is processed is noticeably less than the ping time to the server.


Again this is only is past experience.. but network data quite often arrives in big batches - then very little - big batches - then very little. Thats made me hiccup rendering updates in the past. Not so much processing the updates (cause this has to be done anyway) but rather just reading the data in. Running the data read and process in another thread alieviated this..

It may have been because of other factors in the couple of cases I've tried but since we're relying on entirely anecdotel evidence here anyway.. what the hey. Smiley

Kev

Offline Vorax

Senior Member


Projects: 1


System shutting down in 5..4..3...


« Reply #15 - Posted 2005-01-08 15:22:53 »

Quote
Java3D is known for being slower than other solutions. Again from the knowledge of others I've been informed this has alot to do with their use of synchronisation. Hence people like Xith didn't bother and got way better performance.


I agree it is slower...alot slower, and I agree alot of it is to do with synchronization, but it is also to do with the amount of layers you pass through before actually doing work that is valuable for your game.  J3D seems focused on making the programmers life easier at the expense of performance.  

I developed my own scene graph as part of this engine and I do comparisions (I have a duplicate of the capabilities in Java 3D...which was the first attempt at this 7 months ago).  In my worst case scenerio, the Java 3D runs at 21 FPS, in my engine it runs at 54 FPS.  The Java 3D has only rendering logic and animatoins though.  The scene is identical and the graph is almost identical (my SG can have transforms assigned directly to geometry objects.  like J3D I do all matrix calculations...but a bit differently and I only support float for performance (no doubles)

I have also implemented a branch level matrix stack that exactly duplicates what Open GL does internally with the modelview stack (push, pops, mul's, translate, rotate, dot's), this avoids alot of Jogl calls and keeps all transformation data aviable at all times. By basically writing parts of Open GL (not the interface, the specification) as Java you can improve performance alot.  I have a grand total of one push, one pop and one matrix multiply in terms of JOGL calls beyond vetex pumping.

Quote

This being an increadibly trivial engine test I don't think its really relevant.


If this is a trivial test of the engine, I am not sure what you would consider a real test :|  I have seen alot of Java games and none (except the Agent 9 stuff) seem to be pushing things even close to as hard as I am so far.  Maybe I just haven't seen as much as I think I have.

Quote

Like you I can't talk for industry experience but I have tried lots of different ways of writing games in Java over the last 3 years. I've certainly come down on the side that one thread is better (at least where logic/rendering are concerned - networking is still up for debate in my mind).

Kev


Well, I do have a little game industry experience (not in Java though).  I have done some work for Activision and I am in the credits of at least one off the shelf AAA game from them (Star Trek: Elite Force II)...not lead developer though Wink  I know enough people at UBI Soft, Activision and Raven, that I am sure I could get a job in the industry, but my real job pays alot more then gamming industry would and has alot better hours Wink  So the only way for me to go is start a company and either buy an engine or build my own... building is cheap and can be thrown out if necessary.  

Offline Vorax

Senior Member


Projects: 1


System shutting down in 5..4..3...


« Reply #16 - Posted 2005-01-08 16:07:58 »

Quote


That's not "evidence". That merely says their coders are poor or alternatively a lot about how self-fellating their promotional speakers are. GDC talks aren't selected for quality and accuracy so much as for "fame" and "contentiousness" and "interest" of what is going to be said.


True, these things need to be taken with a grain of salt (or a bag full some times Wink )

Quote

Not really single versus multi-threading, this is instead a discussion of "how to workaround bugs in the API design where you are only provided with blocking calls".
Quote


I agree but it illustrates where a thread can help you.  The .9 wasted in that discussion affects both the GPU and the CPU becuase the GPU is idle and the CPU will be writing to the front buffer instead of doing something useful.

Quote

It is a base assumption of writing a single-threaded game that all your calls which can be are asynchronous and predictable. If you have that, there's no advantage to using threads. In theory, you ought to have that available. In practice, lots of things annoyingly aren't feature-rich enough.

e.g. from a developer perspective I have no need to block on waiting for a vsync, I should instead be able to check how long I've got until the next vsync happens. Much much more useful.


I don't think I am explaining what my engine is doing very well.

One thread is doing everything except the actual GL calls (the engine thread).  It does this at a target rate of 62FPS.  The other is doing nothing except GL calls (the render thread).  

When the renderer is ready for more geometry, it uses the reference to primitivate data last sent to it by the engine.  All logic and calculations have been predone on the geometry.  This reference passing is the ONLY place that synchronization could actually occur.  This is memory expensive though becuase the engine maintains a copy of the original geometry, transformed geometry and a the last transformed geometry that is actually being rendered.  Only for non-static geometry though.  Static geometry is shared by both the engine and renderer threads.

If the engine thread finishes before the renderer thread (which means renderer FPS has dropped below 62 FPS), the game state is updated.  This means that the engine thread will continue determining the next frame of game state, but the renderer may not actually render it.  

The renderer is not blocked though.  It can render the previous set of data if the engine has moved on to yet another frame.  In the worst case, the engine will be rendering frame 1 when the engine is actually creating frame 3.  As geometry lessens, the renderer will get back into synch and be rendering one frame behind the engine.

If the renderer finishes before the engine (which means renderer FPS has exceeded engine FPS), then the renderer will simply reproduce the last frame sent to it by the engine.  If the renderer is operating 2 or more frames above its target FPS, it can also yield (yes my engine has yield code INSIDE the main loop Wink ) to give the engine some more power.   If the engine doesn't need the power, it gives it back with it's own yield and thus FPS can rise well above the target fps.

The result is a consistant game state regardless of the amount of geometry rendered (as long as the engine FPS rate does not drop below 62...I can't imagine the complexity or bad code it would take to cause this).

The rendering is an extremley tight loop that does NO calculations, isn't blocked by the game state and serves the sole purpose of pushing primitive level GL calls and swapping the buffer as fast as it can.

Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #17 - Posted 2005-01-08 20:04:20 »

Quote


Again this is only is past experience.. but network data quite often arrives in big batches - then very little - big batches - then very little. Thats made me hiccup rendering updates in the past. Not so much processing the updates


So, you mean you failed to do your offline RT scheduling adequately for the particular problem Smiley. i.e. you didn't put a limiter in of how much network data you would process per frame, and ended up processing "as much as happened to be there". It's no big leap to put in a limiter, e.g. "I will only process a max of 3 network messages per frame, and the rest I shall delay until next frame". Compared to network latency, shunting messages back a couple of frames isn't usually a problem.

So long as you bear in mind that a single threaded game-loop is an RT scheduler (i.e. you ahve to work out in advance how long every method call will take and personally allocate how much time its' going to be given at runtime, and scheudle those slots so that you meet your requirements) you don't generally have problems using it.

The fact that doing this is boring and any modern OS should have a decent enough thread scheduler is why I tried to do java games multi-threaded, until the AWT/swing stuff bit me on the ass. After that I just never bothered going to multiple threads Smiley. Except where e.g. I already had a module with it's own selector-plus-private-thread and re-used it as-is...

malloc will be first against the wall when the revolution comes...
Offline kevglass

JGO Kernel


Medals: 172
Projects: 23
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #18 - Posted 2005-01-08 20:14:45 »

Yeah, you're probably right. Makes sense when you put it like that...

Kev

Offline Raghar

Junior Member




Ue ni taete 'ru hitomi ni kono mi wa dou utsuru


« Reply #19 - Posted 2005-01-09 17:00:30 »

Quote
Isn't this generally the case with all cards, on purpose? AGP is designed to send data one way only, pretty much. glReadPixels sucks for this reason. PCI-X, on the other hand...

Actually It might be PCIExpres, I remember comparisson of two cards from NVIDIA and ATI on OpenGL board, and that 3x speed difference towards CPU was just on ATI card.
Quote

The fact that doing this is boring and any modern OS should have a decent enough thread scheduler...

This theory would fail when met with windoze. I still doesn't know why multithreaded programs works better with older versions, than with XP.
This however doesn't mean you shouldn't use less than 3 threads. I once said a game could use more than 10 threads.
2 - 4 for AI
1 for graphic engine
1 to 3 for game engine
1 for sound engine
1 to 2 for world engine
(1) possible for network
(1) for lazy decompression of textures and background saving.
and sheduler
Sometimes it would be the best idea to call Thread.yieldToThread(Thread t);
Of course some of them could be deamon threads, but my point is AI needs at least one own thread for thinking in free CPU time or it would be dumb.
Another advantage of this is when all is done it could nicely sleep and let CPU cool a little, a very nice feature for lastest processors.
Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #20 - Posted 2005-01-09 18:01:28 »

Quote

Of course some of them could be deamon threads, but my point is AI needs at least one own thread for thinking in free CPU time or it would be dumb.


Except that most games don't do this, and most AI algorithms are specifically designed (or tweaked from their original, non-gaming, versions) not to do this.

So, "needs" is not quite the right word Smiley.

I'm a fan of QoS processing for games, so I rather like the AI algorithms designed to be multipass or time-limited (i.e. so that you can control to some extent from wihtin the main game-loop how much time the AI code will spend executing, responding in real time to peaks and troughs in the frame rate creation time).

To be honest, Java's threading API's are far too weak to do what you suggest IMHO, and the same is true for vanilla native threading, unless you don't mind writing a differnt version of your game for each different OS version (cos they keep changing from version to version). This is one of the other reasons why single-threaded games dev is the norm: threading API's are very poor in general, in terms of expressive power, with far too little control of the scheduler.

For instance, there's no API call for me to say "The AI thread should be given between X ms and Y ms every Z ms, except when the frame-render thread has used more than P ms in the current frame or more than Q ms total over the 3 previous frames". (note: this is the kind of logic that the scheduler has internally, it's just that the OS doesn't expose it to you as a programmer. There are some funky cool OS's that *do* expose it, in great detail, and I love them, but ... they're research OS's, or ultra-niche embedded systems, etc)

Which is exactly the kind of logic you need to do. The expressivity of plain threading API's is way too poor. There are plenty of threading API's that do provide this level of support, for specialized niches, but IIRC none of them are mainstream *yet* (please someone correct me if I'm wrong here; it's been a while since I checked what standard threading API's were). Given the amount of interest in recent years in massively improving linux's threading systems, there's a possibility that some big leaps could be about to appear. But...who cares until it's also there on windows?

malloc will be first against the wall when the revolution comes...
Offline princec

JGO Kernel


Medals: 391
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #21 - Posted 2005-01-10 12:41:25 »

Like I keep trying to explain to people over and over again, threads are an operating system concept designed to keep processors busy when they are waiting for I/O to complete. They're not for scheduling tasks, for which you either need: a RTOS and appropriate APIs (JSR001?); or algorithms designed to work in sequential steps.

Give the AI to a thread and the next thing you'll find is that the gidrahs just sit around doing nothing because the AI thread is mysteriously never scheduled to run.

Cas Smiley

Offline rreyelts

Junior Member




There is nothing Nu under the sun


« Reply #22 - Posted 2005-01-10 15:06:45 »

Quote
Like I keep trying to explain to people over and over again, threads are an operating system concept designed to keep processors busy when they are waiting for I/O to complete.

Right - because multi-cpu machines are a figment of everyone's imagination, and no one would ever write an application to take advantage of them. *cough* *cough*

Cas, I think you're living too much in the past. Take a look at http://www.gotw.ca/publications/concurrency-ddj.htm. (Btw, in case you didn't know, Herb Sutter has some pretty serious creds). Cpu performance just isn't scaling like it used to. It's why ALL the big names (AMD, Intel, IBM, Sun, etc...) have already gone multicore. Sun has special plans for massive parallelism via CMT (Niagra).

This isn't way off in the future, Cas. It's already happened. You'll probably be programming on a multicore machine in two years.

God bless,
-Toby Reyelts

About me: http://jroller.com/page/rreyelts
Jace - Easier JNI: http://jace.reyelts.com/jace
Retroweaver - Compile on JDK1.5, and deploy on 1.4: http://retroweaver.sf.net.
Offline princec

JGO Kernel


Medals: 391
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #23 - Posted 2005-01-10 15:56:11 »

What WORA programming is about, is guarantees of service, and until a Thread is guaranteed to execute precisely the amount that we want them to, they're no use to us who want to write code that runs reliably everywhere. The concept we want is not Threads, it's "Tasks", or whatever the realtime boys call 'em.

Case in point: in a LWJGL app, merely changing the main thread priority to Thread.MAX_PRIORITY causes a total freeze of the display under some ATI drivers because the ATI drivers stop getting any time (inexplicably).

Then of course there's the whole synchronisation and complexity issue.

But who am I to tell anyone, eh, I've only written a few games Wink

Cas Smiley

Offline rreyelts

Junior Member




There is nothing Nu under the sun


« Reply #24 - Posted 2005-01-10 16:50:52 »

Quote
What WORA programming is about, is guarantees of service, and until a Thread is guaranteed to execute precisely the amount that we want them to, they're no use to us who want to write code that runs reliably everywhere.

That's bullhockey Cas. I write multi-threaded code that executes on many platforms (Windows, Linux, Solaris, AIX, and Irix to name a few).

Quote
Case in point: in a LWJGL app, merely changing the main thread priority to Thread.MAX_PRIORITY causes a total freeze of the display under some ATI drivers because the ATI drivers stop getting any time (inexplicably).

Wow, you set a Thread to the highest possible priority, and then you're surprised when it starts starving out other threads? First rule of thumb, Cas - You are almost always doing the wrong thing if you are setting a thread's priority. You should manage allocation of time to threads through synchronization mechanisms, not through thread priorities.

Quote
Then of course there's the whole synchronisation and complexity issue.

Yes, multithreading is not simple, and we're seeing the proliferation of tools to deal with that complexity - new languages (Erlang), new language tweaks (Flow Java), and new libraries (java.util.concurrent). Aside from that, if you think people are going to prefer your simpler non-concurrent game, when it's only using one-half or one-quarter of the processing power other more-complex concurrent games are using, I have a news flash for you.

Quote
But who am I to tell anyone, eh, I've only written a few games Wink

Who am I to talk about multithreading? I've only been doing it professionally for a decade on apps ranging from medical imaging to remote app servers. Oh, and another tip, Cas. Realtime scheduling is about anything but full-blown performance. It's totally about QoS. Most apps that require realtime scheduling (typically embedded devices) don't need any kind of real performance (cause they're running on a 2Mhz microcontroller as it is).

God bless,
-Toby Reyelts

About me: http://jroller.com/page/rreyelts
Jace - Easier JNI: http://jace.reyelts.com/jace
Retroweaver - Compile on JDK1.5, and deploy on 1.4: http://retroweaver.sf.net.
Offline rreyelts

Junior Member




There is nothing Nu under the sun


« Reply #25 - Posted 2005-01-10 17:37:36 »

I thought it was apropos that Slashdot just posted this to its front page: http://slashdot.org/article.pl?sid=05/01/10/1839246&tid=142&tid=118

God bless,
-Toby Reyelts

About me: http://jroller.com/page/rreyelts
Jace - Easier JNI: http://jace.reyelts.com/jace
Retroweaver - Compile on JDK1.5, and deploy on 1.4: http://retroweaver.sf.net.
Offline kevglass

JGO Kernel


Medals: 172
Projects: 23
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #26 - Posted 2005-01-10 18:09:34 »

Arn't we just talking about different scales of complexity here?

Multithreading is positively worth it if you're going to get multiple CPUs involved. However, for the style of games Cas is talking about thats simply not the target market. If you're using a single processor machine thread isn't going to give you an significant performance increase since there always be overhead in swapping threads. By segmenting your main loop into sections all you're actually doing is creating a specialized scheduler yourself instead of relying on the more generic one.

You *could* rely on the thread management of the OS using its heuristics to decided which thread should get more time or you could use some domain knowledge to decide before hand.

Other than the lack of control over scheduling (and the added complexity in getting that control) I'm struggling to see what the significant difference is between a custom game loop and threading everything seperately.

I'm probably just dense but I'd quite like to understand.

Kev

Offline princec

JGO Kernel


Medals: 391
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #27 - Posted 2005-01-10 18:32:48 »

Basically, that's about the size of it. You have to code to assume a single processor and a crap OS scheduler. Well, not even crap - just not guaranteed predictable. This is totally about QoS - if the AI doesn't work on some computer then it doesn't work.

<edit>And what's more we have to write to assume a certain amount of work is done on every task irrespective of the power of the target CPU.

By day, I write big, big multithreaded multitier client server apps.

Cas Smiley

Offline rreyelts

Junior Member




There is nothing Nu under the sun


« Reply #28 - Posted 2005-01-10 18:43:53 »

Quote
Basically, that's about the size of it. You have to code to assume a single processor...

No you don't. Well-written multi-threaded code runs fine on an arbitrary number of processors, Inf > N > 0, just like well written graphics code scales from a Radeon 9000 to a Radeon 9800 Pro.

Again, your programs are just going to be outclassed Cas, when the average desktop computer is a multicore system.

God bless,
-Toby Reyelts

About me: http://jroller.com/page/rreyelts
Jace - Easier JNI: http://jace.reyelts.com/jace
Retroweaver - Compile on JDK1.5, and deploy on 1.4: http://retroweaver.sf.net.
Offline princec

JGO Kernel


Medals: 391
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #29 - Posted 2005-01-10 19:49:45 »

But meanwhile the multithreaded is going to fail. And fail it will. But we must now agreee to disagree, as we are on a level about 3 layers of Heaven above the OP and waaay off topic!

Cas Smiley

Pages: [1] 2
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Pippogeek (39 views)
2014-09-24 16:13:29

Pippogeek (30 views)
2014-09-24 16:12:22

Pippogeek (20 views)
2014-09-24 16:12:06

Grunnt (46 views)
2014-09-23 14:38:19

radar3301 (28 views)
2014-09-21 23:33:17

BurntPizza (64 views)
2014-09-21 02:42:18

BurntPizza (36 views)
2014-09-21 01:30:30

moogie (42 views)
2014-09-21 00:26:15

UprightPath (51 views)
2014-09-20 20:14:06

BurntPizza (54 views)
2014-09-19 03:14:18
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!