Ah, I see, it might have been due to my misuse of wait() and notify().
 In any case, I remember that even sleeping the thread caused
decreased fps rate, (which I took as increased cpu usage.)

I mentioned the pool thread, not because I implemented one, but
because I avoided implementing one and  avoided dealing with polling
(and timestep calculations) by using the TimerTask class.  Which uses
a more efficient thread pool/looping that I could implement with
wait() and notify().

And in this case, yes it was the thing that worked the best first, but
thanks for the useful information/code.  I will try to apply it when I
revisit the code.

On Sun, Apr 11, 2010 at 12:25 PM, Bob Kerns <r...@acm.org> wrote:
> You say: "So, say I have the game loop logic in a thread like that,
> using the
> render fps average as a counter, I've noticed that the fps drops when
> using more than one thread, even if it's just running in an empty
> loop. "
>
> Um, ESPECIALLY if it's running in an empty loop. The point is, you
> don't want it to run AT ALL unless it has something to do.
>
> Handler is one way to do this. Sleep never helps you do this, UNLESS
> "something to do" is purely based on time.
>
> What your code below is doing is called "polling". Polling is the
> technique of last resort, because your thread has to wake up
> periodically even if there's nothing to do.
>
> That may not be serious -- and sometimes it's your only choice. But
> the ideal is to block, waiting to be told there's actual work to do.
>
> "I remember timing this was I would constantly send network data to
> the
> network thread with a timestamp, then I would check how long it took
> for that message to make it to the game loop by determining the time
> difference. "
>
> This doesn't sound like a good way to measure, as there are too many
> variables.
>
> If you created the timestamp at the point of sending it to the
> handler, and how long it took before the handler began executing,
> you'd have a valid measurement of the latency. However, even latency
> is not telling you efficiency.
>
> Using a Handler does not involve creating a thread, so I'm not sure
> why you mention that you use a thread pool. Indeed, if you're using
> multiple threads to do intermittent work, a thread pool is a good
> idea. However, since you have only one main processor, if you're doing
> work that doesn't block, you may find no advantage, and even a small
> performance DECREASE, by having more than one thread in your pool!
> (There can be other reasons to have more than one thread, however; I'm
> just discussing performance).
>
> Handler is presumably doing something like this to queue:
>                synchronized (m_actions) {
>                        m_actions.add(r);
>                        m_actions.notify();
>                }
> And something like this to pull from the queue and execute:
>                while (true) {
>                        Runnable action = null;
>                        synchronized (m_actions) {
>                                while (m_actions.isEmpty()) {
>                                        try {
>                                                m_actions.wait();
>                                        } catch (InterruptedException e) {
>                                        }
>                                }
>                                action = m_actions.remove();
>                        }
>                        action.run();
>                }
>
> When there's nothing to do, the thread is waiting in the wait() call,
> not running, not consuming any CPU. (It does consume some significant
> memory; idle threads are not free!)
>
> (Don't worry about that inner loop and catch of InterruptedException
> -- nobody will be interrupting, that's a holdover from the early days
> of Java).
>
> When something is placed in m_actions, the thread running the loop
> *immediately* becomes runnable. Whether it runs immediately depends on
> whether it has to compete with other threads which are also runnable.
> And more importantly, if it was NOT in the wait() call -- that is, it
> is still running an earlier request, then it will not run the new
> runnable until the old one completes, and it goes around the loop
> again to check.
>
> This loop NEVER runs unless there is work to do -- yet it's
> immediately runnable when there is. (The exception is that it checks
> if something is already queued on first entry). This is the ideal.
> With polling, you have to check if there's work to do. The check here
> IS run before waiting after just completing work, but the thread was
> already awake in this case. It never wakes up just to see if there's
> work.
>
> "The game loop I'm using is SUPPOSED to be 60fps but will undoubtedly
> vary, I use the Timer class's scheduleAtFixedRate to automatically
> take care of the timestep adjustments/wait time.
> Since the timer class uses a thread pool, it doesn't have an overhead
> of thread creation.  I don't have to handle calculating how long to
> sleep to maintain a constant rate, and is quite efficient.
> I've achieved a smooth display, and the physics progresses a step at
> each game loop iteration.
> This has worked well for me. "
>
> If that's all worked well for you, I'm NOT telling you that you need
> to change it. However, there's a number of ways this can break down
> when you really push the limits.
>
> But a guiding principle is -- Do The Simplest Thing That Could
> Possibly Work. It sounds like you've achieved that, for now. Or maybe
> "The First Thing That Worked", and sometimes that's a good choice,
> too! :=)
>
> If someday you find it no longer meeting your needs, you can take
> these other things into consideration. Or others reading this thread
> may find them useful.
>
> On Apr 10, 6:34 pm, Miguel Morales <therevolti...@gmail.com> wrote:
>> Ok, like I said I may have missed something, but say I have something like 
>> this:
>>
>> class MyThread extends Thread
>> {
>>     run()
>>     {
>>         while (something)
>>         {
>>            if (something_else) //perhaps input has changed, or we have
>> data in a socket
>>            {
>>                //do some work, not idle
>>            }
>>            else
>>            {
>>                //no work to do
>>            }
>>            Thread.sleep(x); //maybe needed, based on implementation
>>         }
>>     }
>>
>> }
>>
>> So, say I have the game loop logic in a thread like that, using the
>> render fps average as a counter, I've noticed that the fps drops when
>> using more than one thread, even if it's just running in an empty
>> loop.
>>
>> Using a looper object forces me to communicate with the thread by
>> posting messages to its handler.  Say I have a network thread that
>> just got a message and wants to let the game loop of a new data
>> available, or the UI thread wants to let the game loop know that the
>> input state has changed.  It can be done using a handler, or using a
>> lock to protect a data buffer.
>>
>> So say in the game logic loop we constantly check the state of some
>> variable and doing work accordingly, I have found it's much faster to
>> use a lock around an object than it is to post to a handler.  The way
>> I remember timing this was I would constantly send network data to the
>> network thread with a timestamp, then I would check how long it took
>> for that message to make it to the game loop by determining the time
>> difference.
>>
>> I was working directly with bytes, as to avoid any sort of
>> serialization overhead.
>>
>> The game loop I'm using is SUPPOSED to be 60fps but will undoubtedly
>> vary, I use the Timer class's scheduleAtFixedRate to automatically
>> take care of the timestep adjustments/wait time.
>>
>> Since the timer class uses a thread pool, it doesn't have an overhead
>> of thread creation.  I don't have to handle calculating how long to
>> sleep to maintain a constant rate, and is quite efficient.
>>
>> I've achieved a smooth display, and the physics progresses a step at
>> each game loop iteration.
>> This has worked well for me.
>>
>>
>>
>> On Sat, Apr 10, 2010 at 12:57 PM, Bob Kerns <r...@acm.org> wrote:
>> > If a thread is hogging the CPU, it is *BY DEFINITION* not idle. And
>> > vice versa.
>>
>> > An idle thread will be waiting on something. Either a synchronization
>> > lock, or an object using wait(), or some blocking IO call. This may be
>> > buried inside some other code, of course.
>>
>> > I would suggest wondering why you thought this. How are you
>> > determining what threads are consuming what CPU? Either you have some
>> > sort of methodology error, or interpretation error.
>>
>> > I would wonder about your statement about a Looper and Handler being
>> > slow. I haven't read the code, but the implementation I would expect
>> > would be very simple, and using wait/notify. In other words, they
>> > SHOULD be fast. If you find them slow, I'd again check your
>> > methodology -- and if you can confirm, I'd suggest filing a bug
>> > report, since that's something that could be improved and would
>> > improve things for the entire platform.
>>
>> > Re 60 fps game logic -- some alternatives to consider that may be
>> > better choices in some circumstances. I'm only considering physics
>> > here; I'm not sure what the time constraints on other game logic might
>> > be:
>>
>> > If you're doing your physics calculations correctly, you won't be
>> > constrained to a constant game logic rate. You may be able to vary
>> > your simulation time step to maintain a more steady render rate (at
>> > the cost of some accuracy), and even vary it between different parts
>> > of the model, e.g. critical portions (e.g. collisions) run a higher
>> > rate, while running a longer timestep for portions not subject to time-
>> > varying forces.
>>
>> > If smooth display is more important than physical accuracy, running
>> > physics after each frame, driven by actual elapsed time, may be the
>> > way to go. You can trigger that as you're about to flip the scene, so
>> > it overlaps the GPU. You may prioritize your fast-moving stuff, and
>> > only update a portion of your model on each frame.
>>
>> > Also, you may be able to apply Level of Detail (LOD) control to your
>> > scene -- including fewer polygons when the overall frame rate drops
>> > (due to either graphics or physics).
>>
>> > All that is a lot more complex, of course, but may let you push the
>> > envelope a bit further.
>>
>> > On Apr 9, 7:42 pm, Miguel Morales <therevolti...@gmail.com> wrote:
>> >> I may be completely wrong on this, but I've found that threads hog the
>> >> CPU even when idle.
>>
>> >> The way that has worked well for me is to have the render thread, and
>> >> the logic timer.
>>
>> >> (using a looper and communicating via a handler can be slow, from my
>> >> experience locks are faster)
>>
>> >> To keep things simply I use a TimerTask to simulate a 60fps game logic
>> >> rate (game_loop_timer.schedule(game_loop_task, 0, 17);).  The game
>> >> logic rate can vary based on what needs to be done.  (i.e pathfinding,
>> >> network syncing, etc.) and sets a scene to the buffer.
>>
>> >> The render thread stays constant by simply drawing what's on the scene
>> >> buffer at every onDraw.
>>
>> >> I use a single lock to keep the scene buffer safe between the two threads.
>>
>> >> It's actually pretty simple, and I only really need two classes.
>>
>> >> I highly recommend reading articles about this, here are some of my 
>> >> bookmarks:http://gafferongames.com/game-physics/fix-your-timestep/http://stacko......
>>
>> >> For input, I use a lock for the state of the hardware.  (i.e. when the
>> >> screen is being touched, I set a boolean isTouched to true and use a
>> >> lock to safely read/write from the threads.  However, a queue/handler
>> >> is really the way to go when it comes to that since it's not as
>> >> time/latency sensitive.
>>
>> >> On Fri, Apr 9, 2010 at 6:29 PM, Lance Nanek <lna...@gmail.com> wrote:
>> >> > There are a lot of built in classes in Android and Java that you can
>> >> > use to avoid having to write any synchronization or lock code
>> >> > yourself. In my case GLSurfaceView sets up my render thread. I use
>> >> > HandlerThread for my game thread. The game thread sends an update
>> >> > object detailing all the draw commands needed for a frame to the
>> >> > render thread via a BlockingQueue. The render thread returns it via
>> >> > the game thread's Handler. The UI thread tells the game thread about
>> >> > input via the game thread's Handler as well. These classes are in the
>> >> > android.os and java.util.concurrent packages.
>>
>> >> > On Apr 9, 6:36 pm, Eddie Ringle <ed...@eringle.net> wrote:
>> >> >> Okay, I figured I could just pass the Activity through parameters, but
>> >> >> wanted to know if a better way was possible.
>> >> >> Thanks for all the help everyone.
>>
>> >> >> On Apr 9, 5:56 pm, Mario Zechner <badlogicga...@gmail.com> wrote:
>>
>> >> >> > That depends on what kind of input you need. If your game is happy
>> >> >> > with just checking the current state of the accelerometer/touch 
>> >> >> > screen/
>> >> >> > keyboard/trackball simply polling will do the trick. This means that
>> >> >> > in the UI thread, where you have your event listeners installed, you
>> >> >> > simply save the last state reported to you. In your logic thread you
>> >> >> > can savely access this state even without synchronization as it will
>> >> >> > only be composed of plain old data types like booleans or ints (of
>> >> >> > course there are cases where you catch the x coordinate of the
>> >> >> > previous event and the y coordinate of the current event but i dare
>> >> >> > say that the differences are so tiny, it doesn't make a difference).
>>
>> >> >> > Other things might need event based input handling, like a GUI you
>> >> >> > implement yourself with say OpenGL. In that case you will need a 
>> >> >> > queue
>> >> >> > that gets filled in the Android GUI thread by the listeners you have
>> >> >> > installed for the input devices. The logic thread acts as a consumer
>> >> >> > and takes the events from the queue. As you are working with a 
>> >> >> > complex
>> >> >> > data structure you need to synchronize the adding and removing of
>> >> >> > events to and from the queue in both the Android GUI thread and your
>> >> >> > logic thread. This is a classical consumer/producer pattern which can
>> >> >> > be found frequently in multithreaded applications. Check out Robert's
>> >> >> > site athttp://www.rbgrn.net, i think he wrote an article on that sort
>> >> >> > of thing once.
>>
>> >> >> > it basicaly boils down to this (pseudo code, written from the top of
>> >> >> > my head, will not compile)
>>
>> >> >> > public class GameActivity extends Activity implements
>> >> >> > MotionEventListener
>> >> >> > {
>> >> >> >    Queue<Event> events = new Queue<Event>();
>>
>> >> >> >    public void onTouch( MotionEvent event )
>> >> >> >    {
>> >> >> >       synchronized( events )
>> >> >> >       {
>> >> >> >          events.add( new Event( event.getX(), event.getY() );
>> >> >> >       }
>> >> >> >    }
>>
>> >> >> > }
>>
>> >> >> > public class GameLogic
>> >> >> > {
>> >> >> >    GameActivity activity;
>>
>> >> >> >     public GameLogic( GameActivity activity )
>> >> >> >     {
>> >> >> >        this.activity = activity;
>> >> >> >     }
>>
>> >> >> >     public void handleInput( )
>> >> >> >     {
>> >> >> >         synchronized( gameActivity.events )
>> >> >> >         {
>> >> >> >             // proces events here
>> >> >> >         }
>> >> >> >     }
>>
>> >> >> > }
>>
>> >> >> > Now, a couple of comments: You don't want to instantiate a new Event
>> >> >> > everytime a listener method in the GameActivity is called. You will
>> >> >> > need to implement a simple object pool and reuse events. That way the
>> >> >> > garbage collector will stay calm. Also note that the design above is 
>> >> >> > a
>> >> >> > bit nasty, i would directly pass the GameActivity to the GameLogic
>> >> >> > among other things. But that's up to you.
>>
>> >> >> > Polling input handling would work like above but without a queue and
>> >> >> > without the need for the synchronized blocks. All you do is set some
>> >> >> > members of GameActivity, say touchX and touchY in the
>>
>> ...
>>
>> read more »
>
> --
> You received this message because you are subscribed to the Google
> Groups "Android Developers" group.
> To post to this group, send email to android-developers@googlegroups.com
> To unsubscribe from this group, send email to
> android-developers+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/android-developers?hl=en
>
> To unsubscribe, reply using "remove me" as the subject.
>



-- 
http://diastrofunk.com, http://developingthedream.blogspot.com/,
http://www.youtube.com/user/revoltingx, ~Isaiah 55:8-9

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to