1

Assume my application runs 2 threads (e.g. a render thread and a game update thread). If it is running on a mobile device with multi-core CPU (typical nowadays), can I expect that threads are assigned to different cores automatically when possible?

I know the underlying OS kernel (Android linux kernel) decides scheduling. My question is whether I need to do anything additional to enable multi-core usage, or is it automatic and transparent?

Thomas Calc
  • 2,994
  • 3
  • 30
  • 56

1 Answers1

3

What you need to do is to allow the two threads to run independently as possible. If you have two threads which are always waiting for each other, they might run on the same core to save power. (Because it might appear there is nothing to be gained by having to cores being used)

the case is the following: first thread decodes a bitmap, while renderer uploads the texture of the previous bitmap to GPU. The first thread goes to sleep if nothing to do; then wakes up if a bitmap needs to be decoded again.

I suspect this is a good example where two threads won't help because decoding the bitmap should be faster than "uploading" This means you have two situations

T1: decoding bit map, 
T2: waiting for a bit map.

or

T1: sleeping
T2: uploading a bit map.

or

T1: sleeping
T2: waiting for a bitmap.

Can you see how there is no situation where both threads are needing to run (or perhaps rarely) This may be no faster, or even slower than just doing this

T1: decodes bitmap.
    uploads bitmap.
    waiting for a bitmap.
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Does the system monitor such a behavior of my app somehow, and decides based on some heuristic? How "permanent" can be the decision (if you have such an info)? BTW the case is the following: first thread decodes a bitmap, while renderer uploads the texture of the *previous* bitmap to GPU. The first thread goes to sleep if nothing to do; then wakes up if a bitmap needs to be decoded again. – Thomas Calc Jun 23 '13 at 10:04
  • @ThomasCalc The system doesn't need to monitor itself as it is the one doing it. If you have only one runnable thread at any one time, it can use one core. (even if there are hundreds of waiting cores) If there is two runnable threads for any length of time (because they are not waiting for each other) they can run at the same time. – Peter Lawrey Jun 23 '13 at 10:17
  • Regarding your comment: thanks, it's more clear now. Regarding your updated post: are you sure decoding e.g. an 1024x512 png (including reading it from external storage) is faster than uploading the Bitmap to texture memory? Yes I wasn't clear; by decoding I also meant the time while it's read from disk (BitmapFactory.decodeStream from asset). – Thomas Calc Jun 23 '13 at 10:26
  • @ThomasCalc It can work, but you have to have a good example where two threads at runnable at the same time for a while. Note: the OS is also trying to minimise power usage which means it might avoid starting a core unless it needs to as this potentially doubles the power consumption. It might say half a second, but your threads might be finished in that time. – Peter Lawrey Jun 23 '13 at 10:27
  • Also Android phones tend to reserve a core for the OS and system stuff which means one cores is dedicated for music, phone, display etc while the other cores can do whatever. In a two core phone this might not multi-thread so well as a result (but prevents your phone stopping for short periods of time, like windows can.) On an Samsung S3 phone for example if you run `top` it says there are 3 cores instead of 4. – Peter Lawrey Jun 23 '13 at 10:28
  • I see. Indeed my two-threaded solution proved to be a bit slower than doing everything in the Render thread (which was my old solution), I had thought it's just synchronization overhead. Nonetheless, it is not a nice thing to block a Render thread (with SD card bitmap reading/decode), so conceptually, the two-threaded approach still seems to be the correct one. – Thomas Calc Jun 23 '13 at 10:30
  • Ah yes, sorry, forgot to emphasize something: the Render thread uses "busy-wait", because it needs to render (even if nothing) in the meantime, as Android doesn't like when onDrawFrame takes too long or blocked. (Note that we're behind a loading screen, so FPS doesn't matter.) – Thomas Calc Jun 23 '13 at 10:33
  • 1
    You can still background the work, even if it means it takes a little longer, because you want to maintain interactivity with the UI. This may not use two cores either, unless you try to use the UI at the same time. Using all the cores is not the objective of a system, but good interactivity is much nicer and that should be your priority. – Peter Lawrey Jun 23 '13 at 10:34
  • 1
    You can see exactly what's happening and when by using the "systrace" tool. Android 4.3 (API 18) introduced the ability to add tags to your application as well. See http://developer.android.com/tools/debugging/systrace.html (note the docs currently reflect the pre-4.3 usage). – fadden Jul 26 '13 at 23:12