> >
> >Clearly, in the uniprocessor case, linux-threads is handicapped by
> >having to ask the kernel to switch between threads, because of the
> >1-to-1 implementation model.  I fully agree with that.
> >
> >However, I think the case we're looking at here may be slightly different.
> >In our case, one thread (A) is running on one CPU, and another thread (B) 
> >is running on another.  Thread A holds a lock, thread B wants to acquire it.
> >Once thread A unlocks the lock, thread B could just go ahead and run
> >on the other CPU.  In this case, *neither* CPU would have to context
> >switch.  It would simply be a system call executed on each CPU.
> >
> >Am I missing anything here?
> 
> What was the CPU (B) doing while waiting for the lock to be released by
> CPU (A)?  Normally it would not be just sitting there spinning on trying
> to get the lock but rather it would be putting that thread (process) to
> sleep waiting for a signal - that process is at least as much as a
> context switch to get out of since that is exactly what it would do -
> context switch back to the thread (process) that is asleep when the
> signal comes in.

I looked at the halt and scheduling code in my 2.2.12 kernel source.  
Maybe we need some people with more microarchitectural knowledge here.

The main costs of a context switch come from the fact that the TLB
must be invalidated.  On architectures with a software tlb, explicit
instructions must be issued to that effect.  On the x86, I don't know
when it will happen.  Does executing a "hlt" instruction cause it?
I don't believe so?  Does simply reloading segment registers with new global
descriptors cause this?  Probably.  Does resuming a CPU that has gone
into a "hlt" instruction cause the segment registers to be reloaded,
even if the same process is to be resumed on that CPU?  That is the
question IMO.

I believe that if CPU (B) goes idle while waiting for CPU(A)
to resume it, and after it resumes it will run the same process it ran
before the hlt,  it should *not* incur the same cost as if it switched
contexts and resumed a different process.  At least that's what I conclude 
from looking at kernel/sched.c.  The scheduler there attempts to reschedule 
a process on the CPU on which it last ran.  Why does it do that?
Do I misinterpret that code?  Are there other reasons?

I should mention another source of overhead here: to resume a process
on a different processor, interprocessor interrupts have to be used.
How fast/slow are those on the x86?

> 
> If you design a specific system that runs only two threads on two processors
> then you can easily make this a special case.  However, in the general
> case of an OS like Linux (especially if other programs are also running
> on the same system) there is a strong reason not to just loop on a lock
> until you get it (unless they are micro-locks where the duration of the
> lock being held is significantly less than the overhead of waking up
> someone else - and even then one must look at the number of times this
> happens and the number of contenders)

This is true, but as you stated in your previous paragraph it's not the 
case here.  The locks we're looking at are not implemented as direct spinlocks.

> 
> [...]
> >> Using SysV semaphores as an alternative to mutexes is even worse:
> >> you'd pay the cost of a system call on each mutex operation, not just
> >> on those that contend for the mutex.
> >
> >Is this really true?
> >Why would an implementation that uses test-and-set at user-level
> >and that would fall back on the kernel lock/unlock construct not be 
> >applicable in this case as well as in the signal-based implementation?
> 
> Be careful here - there are other things that may be at work in a
> multi-processor system and thus a system call may always need to be
> involved.  The overhead of such a call can be minimized in the
> non-contended case but only to a certain point.
> 

This is true.
I asked some colleagues here at Utah, and indeed there's systems that always
involve a system call.  Some systems, though, such as HP-UX, can sometimes
avoid system calls by sharing some data structures between userland and
kernel.  However, such an approach has different trade-offs, as you say.

        - Godmar


----------------------------------------------------------------------
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to