• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: relative thread priorities
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: relative thread priorities


  • Subject: Re: relative thread priorities
  • From: Jeff Moore <email@hidden>
  • Date: Tue, 18 Sep 2007 18:43:45 -0700


On Sep 18, 2007, at 5:02 PM, Jeremy Todd wrote:

This sounds reasonable. Is there any way to prevent a thread's priority from
degrading?

You can make the thread have a non-degrading priority, but I forget what scheduling policy that corresponds to and whether or not your process needs root privileges to use it.


If not, are there any guidelines for how often I need to yield
the CPU to avoid degradation?

Yes. You should yield probably at least once every few scheduling quanta. I believe the scheduling quantum for regular threads is 100 milliseconds on X, but you should look that up to be sure.


Threads A and B have perhaps 5 minutes of work to do each, so they are
certainly going to be preempted before yielding explicitly. In both cases,
it's difficult to keep track of "time". They're just a bunch of for loops
and function calls and calculations whose complexity varies depending on
input data, etc.

There must be some differences between the the two threads to get the behavior you described. For A's priority to degrade below B's implies that B is probably yielding the CPU more often than A.


At any rate, rather than keeping track of time, the thing to do is to implement it in the natural terms of your calculations. Generally, there are natural places in the code where you can insert yield such as at the end of an outer loop iteration or after some series of function calls, etc.

Can I err on the side of yielding the CPU too often without any negative
performance impacts?

Probably not. When you yield the CPU, the scheduler very well might schedule a thread from some other process or whatever thread is ready to run. You'll be looking for a balance.


Should I try to check some clock very often, and yield
every N microseconds? I just can't see a clean way to do this without
relying on the OS and thread scheduler to do it for me.

Nah. I'd do what I said above. Just figure out where in your code the yields can happen naturally. I wouldn't sweat the precision too much. Just so that you do it occasionally, is probably the important thing.


Now all that said, I have a question for you. How are you determining what is going on in your threads? In particular, when A is starving, how do you know that it is B that is the cause?

The reason I ask is that on a multi-cpu system, if A is not getting scheduled when B is, there could be a lot of other reasons for this beside priority degradation. It could be the case that you are making an API call on A that is blocking.

I encourage you to use Shark's System Trace profile to take a look at what is really going on. Shark will show you a lot about the thread activity including whether or not your threads are ready to run and what threads are running when you think your threads should be running.


Message: 1
Date: Mon, 17 Sep 2007 15:06:55 -0700
From: Jeff Moore <email@hidden>
Subject: Re: relative thread priorities
To: CoreAudio API <email@hidden>
Message-ID: <email@hidden>
Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes

You've said that you are creating two threads, A and B. The
threads are being set with a precedence of -1 and -2
respectively vs. the main thread. The problem you've stated
is that it appears that thread B is running too often and is
starving thread A even though A has a higher priority than B.
You've also said that depressing the priority of B by a lot
gets the behavior you are looking for.

So given that, I put to you that you do not have a problem
with priorities. The problem you have is that you are not
accounting for the kind of work being done on the two
threads. My guess is that what is happening here is that you
have a calculation running on A that is going compute bound.
This in turn is causing A's priority to degrade to the point
where it is lower than the priority for B.  The fact that
depressing B's priority manually "fixes" the problem is
usually a tell that this is the case. The way to fix this is
to break up the long running calculation in A a little bit by
manually yielding the CPU from time to time.

Another aspect of the problem may be the fact that A and B
are running concurrently on a multi-CPU system. If there are
two processors open and both threads are marked runnable,
then they will definitely run concurrently. If you don't want
that to happen, you'll need to take steps to prevent it, such
as using a mutex or other of the various synchronization
primitives on the system.

On Sep 15, 2007, at 8:06 PM, Jeremy Todd wrote:

Hi,

I'm working on a Carbon-based audio application, and I've recently
tried to understand the OS X thread scheduler. Here is what
I'm trying
to set
up:
- There's a CoreAudio thread which is created as a time-constrained
thread as I understand it. I'd prefer not to touch that thread.
- There's the application's main thread. The priority is apparently
47 for
now, I have no idea whether this is always true.
- Background thread 1 needs to run with lower priority than the GUI
thread (I don't want it to let the GUI become unresponsive, or to
block the audio thread, but otherwise it should run as much as
possible).
- Background thread 2 needs to run with lower priority than
background
thread 1.

As documented in other posts and in some sample code, I can call:
thread_policy_set( .. THREAD_EXTENDED_POLICY .. ) to turn off time-
sharing then thread_policy_set( ..
THREAD_PRECENDENCE_POLICY .. ) to
set each thread's "importance". I'm assuming the main thread has
"importance" of zero.
I set
background thread 1 to have "importance" of -1, and
background thread
2 to have "importance" of -2.

After doing this, I can see that background thread 1 has
priority 46
and thread 2 has priority 45. The problem is that when background
thread
1 is
busy, background thread 2 is still able to run fairly often, to the
point where it significantly degrades the performance of background
thread 1.

If I change this so that background thread 2 has
"importance" of -40,
then things look much better. Background thread 2 is no
longer able to
significantly degrade the performance of background thread 1.

I found a post from Jim Magee back in 2001:

http://lists.apple.com/archives/darwin-development/2001/Oct/ msg00351.h
tml stating that thread "importance" is strictly ordinal.

That would be great if it's true, but from what I'm seeing
above, the
importance is used to set thread priorities, and thread priority
values seem to have some meaning. I've seen lots of posts about the
number 63 being some upper non-realtime limit, and the
number 96 being
a realtime priority. Are these numeric values of priority
documented
or guaranteed anywhere?

I was hoping to avoid worrying about actual thread priority
numbers.
It
seems that the guidelines for being a well-behaved app in a
multithreaded system are to state your needs and leave
everything else
to the kernel. In this case, my needs are that background thread 2
cannot significantly degrade the performance of background
thread 1.
Can anyone point me toward a simple way to express this using the
pthread or Mach APIs?

If there isn't a simple answer I think I'm hoping for some insight
into why my GUI thread has priority 47, and whether this can change
over time (I haven't touched its scheduling policy), or
whether it can
change from computer to computer, and how I can decide what to make
background thread 2's priority to achieve my needs.

Note that I'm not worried about my application with respect
to other
processes running on the system. I'm just trying to get relative
thread priorities working reliably inside my application.

I hope this all makes sense - after several hours of reading older
posts and header files, I wasn't able to come up with a
solid answer,
and this seems to me like a fairly basic need for a multi-threaded
application so I hope I'm missing something obvious.


--

Jeff Moore
Core Audio
Apple


_______________________________________________ Do not post admin requests to the list. They will be ignored. Coreaudio-api mailing list (email@hidden) Help/Unsubscribe/Update your Subscription: This email sent to email@hidden
References: 
 >Re: relative thread priorities (From: "Jeremy Todd" <email@hidden>)

  • Prev by Date: Re: relative thread priorities
  • Next by Date: RE: SetParameter
  • Previous by thread: Re: relative thread priorities
  • Next by thread: How to identify the IAC Driver, so as to ignore it
  • Index(es):
    • Date
    • Thread