[epiar-devel] To thread or not to thread (the video code)
Shawn Reynolds
eb0s at yahoo.com
Mon Dec 28 09:58:15 PST 2009
Thanks, I got that impression about modifying based on fps when I originally spoke with topher, I must of been too tired for that conversation. However reading the e-mail string again I understand the changes proposed are not that at all. Ok so if its based on time elapsed not number of loops then we should have a more accurate timer so networking would be more smooth. So lets think about how network code would play into what we are talking about. Sorry this e-mails going to be rushed...
No Video Thread
You would need a dedicated networking thread that communicates with the server and stores the updates into a data structure as well as sends changes to the server. The main thread would then need to sync the stored changes when it runs, which would be dependent on the number of fps you are getting. Also your sending of updates to the server would be dependent on the drawing as well, because you would not sync your changes as fast at low fps, or update your changes as fast.
So this means you have a server running and 1 user has a really slow computer and is getting 10 fps he is not going to be sending updates to the server as often as the other users getting 30-60 fps. So when you are experiencing low fps the network code will not send as many updates which can cause 2 separate behaviors based on the networking code implementation.
Option 1, causes choppy movement or slugish movement( this assumes were using a networking design where the server manages all position and clients send changes in direction, momentum,etc.. this is great for stopping cheating), the updates would not happen as often so the users movements would not be recognized.
Option 2 causes the lagging users ship to appear to jump on al the non lagging users computers, when large changes occur( this assumes that the clients just sends its coordinates and objects coordinates to the server and the server updates the changes and sends them to the other users)
Video Thread
No problems everyone updates at the same speed. When fps are low only your video is affected you still move at the same speed, register input, and send networking updates at the same speed. Unless of course the users pc is so slow it has affected the other threads, in which case we can boot them from the server.
imho I think its necessary but I defer to anyone that knows network programming well I am not an expert.
Shawn
----- Original Message ----
From: Maoserr <maoserr at gmail.com>
To: epiar-devel at epiar.net
Sent: Mon, December 28, 2009 7:31:34 AM
Subject: Re: [epiar-devel] To thread or not to thread (the video code)
I would like to clear up some confusion regarding the game play speed. I
don't think we're adjusting the game play based on the FPS to be exact,
but that the movement speed is based on the real elapsed time rather than
the elapsed number of frames, if that makes sense. In effect, this would
mean that if on computer A, a player moves at 10 km/h, he would actually
move 10 km in an hour in terms of game distance whether or not it is 10
FPS, 20, FPS, or 30 FPS. I would think this would be conducive to network
play.
On Mon, 28 Dec 2009 03:30:14 -0500, Shawn Reynolds <eb0s at yahoo.com> wrote:
> I like the idea too, it wouldn't be too hard to implement. Especially
> from where I am at with the threading in my branch. I already have the
> drawing code separated out into a separate thread. We could always keep
> it as a separate branch until we feel that it's safe enough to place
> into the full version.
>
> Two items to note.
>
> The main one is... with the two threads you now need two timers, to
> manage each thread. Or additional functionality needs to be added to the
> one timer to manage multiple sessions. I'm not a huge fan of adjusting
> the movement speed based on fps because we only update our fps once per
> sec and it can vary drastically on slower computers when their is lots
> of objects on the screen (iemissiles, lasers). This could then in turn
> cause lots of problems when we start doing networking code. Now I know
> I'm getting into a whole new subject that has not been talked about too
> much but with networking code I would assume that the server would need
> to manage the position of each of connected clients. If their is a wide
> variation in the client computers speed to the servers speed the client
> computers objects will end up jumping a lot as they get updated by the
> server to their actual positions. You cant just have the client
> computers send their new locations to the server
> otherwise it becomes really easy to cheat and because of variations if
> fps your ships speed could end up running faster or slower then someone
> else if your fps is changing a lot. So the benefit of having two threads
> is the draw code can be starved out, causing lower fps, but the updating
> code and networking code can always run ( unless of course your pc is
> really slow in which case it wouldn't meet our min requirements to
> play). You stated that threading the video code is unnecessary well I
> disagree I think it is important for the future.
>
> Oh yeah item two, in our current implementation its easier to leave
> drawing code in the main thread and put all the rest in a separate
> thread. Their are some headaches using open gl from a separate thread
> that is not the main thread.
>
>
>
>
> ----- Original Message ----
> From: Maoserr <maoserr at gmail.com>
> To: epiar-devel at epiar.net
> Sent: Sun, December 27, 2009 8:06:17 PM
> Subject: Re: [epiar-devel] To thread or not to thread (the video code)
>
> I like this idea, could we implement the render manager and triple
> buffering even if we decide against threading?
>
> On Sun, 27 Dec 2009 20:53:45 -0500, Chris Walton
> <chris.r.walton at gmail.com> wrote:
>
>> My promised email :)
>>
>> On Sun, Dec 27, 2009 at 8:47 AM, Christopher Thielen
>> <chris at epiar.net>wrote:
>>
<snip>
>>
>> Interesting.
>>
>>
<snip>
>>
>> I'm not completely sure, partially because I'm not very familiar with
>> OpenGL
>> (I've only worked with DirectX and the Nintendo Wii stuff). One reason
>> could
>> be a weird OpenGL implementation, or a weird driver implementation. The
>> latter isn't too unlikely on a VM - maybe it's just trying to pass
>> things
>> through, which result in a context switch/stall/whatever every call.
>> Using
>> immediate mode as we are isn't particularly helpful either. :)
>>
>>
<snip>
>>
>>
>> Wasn't the minimum spec a 500Mhz P3 with a decent for the time graphics
>> card? If so, it should be playable on that. If threading helps that
>> computer
>> run faster is another issue, of course.
>>
>>
<snip>
>>
>>
>> Threading does not cause timing bugs or memory corruption any more than
>> using an unmanaged language causes memory leaks or driving a car causes
>> a
>> car crash.
>>
>> I guess alot of people haven't worked that much with threading, so it
>> might
>> seem scary, but once you know what's going on, and know what to think
>> about
>> when writing code, it's not too big of a deal. Besides, the way you'd
>> probably do it in Epiar's case (which I'll describe later) would limit
>> the
>> parts of the code where you have to worry about threading to a few
>> places.
>>
>>
<snip>
>>
>>
>> The timer stuff needs fixing either way. However, as stupid as it might
>> sound, doing this might actually result in Epiar running _better_ on
>> certain
>> computers. Old P4s with Hyperthreading will benefit, as will modern
>> multicores.
>>
>>
<snip>
>>
>> I know I'm not going to change your mind on this, but I'll try anyway
>> :).
>>
>> Now, first off, go read this:
>> http://realtimecollisiondetection.net/blog/?p=86
>>
>> My idea here is to have the main thread do everything as it did before,
>> except that our generic DrawWhatever() functions don't actually submit
>> the
>> openGL calls, but insert renderjobs into a renderjob list. The other
>> thread
>> takes that std::vector, sorts them, and issues them. That's pretty much
>> the
>> generic overview of the concept.
>>
>> Now, onto the details. You'll have three renderjob lists. Each renderjob
>> list is a std::vector that has reserve()d some sensible amount of slots
>> in
>> it (for speedyness - I'd say the mean of the last two capacities).
>>
>> One renderjoblist is owned by the graphics thread. It can do with it
>> whatever it wants, of course (it'll likely do its sorting directly on
>> that
>> list). One renderjoblist is owned by the main thread. During sprite
>> updating, they insert their renderjobs into it. Another one is sitting
>> idle.
>> Either it's empty and waiting to be filled by the main thread, or it's
>> full
>> and waiting to be rendered. This concept should probably sound familiar
>> to
>> you: http://en.wikipedia.org/wiki/Triple_Buffering . It's what wikipedia
>> desribes as "page flipping triple buffering", except applied to
>> renderjobs
>> and not the actual backbuffers.
>>
>> I'm gonna break out the pseudo-code, since it's easier, but here's,
>> basically, what the video thread would do:
>>
>> while( !quit )
>> {
>> std::vector< RenderJob >& renderJobList =
>> RenderJobListManager::AcquireReadyList();
>> Sort( renderJobList );
>> Render( renderJobList );
>> RenderJobListManager::ReleaseEmptyList( renderJobList );
>> }
>>
>> AcquireReadyList() blocks until a list is available that the main thread
>> has
>> finished filling with renderjobs.
>>
>> The main thread would keep going exactly as it does now, except in the
>> beginning it calls RenderJobListManager::AcquireEmptyList(), and ends it
>> with ReleaseReadyList(). The Video class or somesuch would keep a
>> reference
>> or pointer to the std::vector<RenderJob> that is currently being
>> rendered
>> into.
>>
>> One other consideration is rendering fonts. Since this isn't done by us
>> but
>> by FTGL, it might seem that it's not initially compatible with the
>> renderjob
>> concept. Au contraire! If you read the above blog post, you'll notice
>> that
>> the keys offer a way to insert commands. One of those might simply be
>> telling FTGL to draw something, so that would simply be done in the
>> video
>> thread.
>>
>> Now, I hope this all makes sense. :)
>>
>> Here's where threading needs to be considered:
>>
>> (1) The RenderJobListManager. This is obvious, but also relatively easy.
>>
>> (2) Synchronizing the quit condition in the video thread. This is even
>> easier than (1).
>>
>> (3) This one could be a bit trickier - A renderjoblist might use a
>> texture
>> that is about to be deleted. One solution is to reference count textures
>> (aka the Image class), with the proper resource management system.
>> Another
>> way would be if an Image receives a ticket when it's queued to be
>> rendered
>> and it waits until that ticket is done rendering before it kills itself.
>> With a 64-bit counter, even if epiar deleted a texture every frame, it
>> would
>> take about 9 billion years until that counter overflows :). Another
>> quick
>> and dirty solution would be to just queue the delete for three frames.
>>
>> Not much :)
>>
>> Of course, I know I haven't convinced anybody, but whatever, just wanted
>> to
>> get it out there. :)
>>
>> -- Chris
>
>
> _______________________________________________
> epiar-devel mailing list
> epiar-devel at epiar.net
> http://epiar.net/mailman/listinfo/epiar-devel
>
>
>
> _______________________________________________
> epiar-devel mailing list
> epiar-devel at epiar.net
> http://epiar.net/mailman/listinfo/epiar-devel
_______________________________________________
epiar-devel mailing list
epiar-devel at epiar.net
http://epiar.net/mailman/listinfo/epiar-devel
More information about the epiar-devel
mailing list