Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Multithreaded Programming : Always use spinlocks for performance?

35 views
Skip to first unread message

Frederick Virchanza Gotham

unread,
Jul 24, 2022, 9:31:15 AM7/24/22
to

I would post this post to a more generic group like "comp.programming.threads" however it's overrun with spam.

Earlier this week I posted on "comp.lang.c++" about a class I'd written to get a main thread and 8 worker threads to cooperate with each other.

I've been doing some testing, and I've tested it 3 ways:
(1) Using spinlocks
(2) Using one semaphore, one mutex and one condition_variable
(3) Using two semaphores per worker thread (i.e. 16 semaphores)

The slowest is No. 2. I haven't identified the exact reason why yet, but it's about 30 times slower than the other two ways.

No. 3 is quite good, but not the best.

No. 1 is the fastest. Is this to be expected? Is the only drawback of using spinlocks that they hog the CPU and so the operating system will be a big laggy?

So if you don't mind the CPU fan getting a bit load and the OS getting a big laggy, are you best to use spinlocks in your multi-threaded programs?

Bo Persson

unread,
Jul 24, 2022, 9:54:23 AM7/24/22
to
A spinlock can be good if it is almost always free. It is low cost to
just test it, and continue without spinning.

A spinlock is really bad if there is a 100 threads spinning on it.


As most of the time with software, there is no simple rule that always
works. Rather usually "it depends".

Bonita Montero

unread,
Jul 24, 2022, 10:42:01 AM7/24/22
to
Pure Spinlocks without any long path over the kernel doesn't
make sense in userland as a thread holding the mutex can be
scheduled away.
Spinning for a mutex a limited number of times can make sense
in rare cases. That's when the mutex has a extremely high lock-
ling-frequency and the mutex is held only a very short time
that spinning results in noteworthy more short paths. Otherwise
spinning for a mutex is below the measurement-error.

Paavo Helde

unread,
Jul 24, 2022, 11:09:53 AM7/24/22
to
It depends on what your goals are. If your goal is to get your program
absolutely as fast as possible, and you have full control over your
hardware and software, then spinlocks might be the solution. This is
assuming you know exactly what you are doing (but in that case you would
not need help from strangers in internet).

We lesser mortals need to write software for real world scenarios where
there are other software pieces the customer wants to run on their
computer, and sometimes they even have audacity to think our software
piece is not the most important one. Getting the spinlocks wrong and
blocking the whole machine needlessly is something which may easily
happen, so I would not consider them unless the profiler says the
standard mutex is becoming a bottleneck. This has never happened so far
to me.

Also, before micro-optimizing the things like locking speed, one should
review the algorithm. I have not found willingness to delve into your
original post, but I see there is a regular mandatory wait in all
faster threads for the slowest one, plus the size of a single task
seemed ridiculously small (8 kB). Even if those impediments are
justified, it would be a pretty special scenario and one would not be
able to draw many general conclusions about multithreading performance
from that scenario.

Bonita Montero

unread,
Jul 24, 2022, 11:40:54 AM7/24/22
to
Am 24.07.2022 um 17:09 schrieb Paavo Helde:

> It depends on what your goals are. If your goal is to get your program
> absolutely as fast as possible, and you have full control over your
> hardware and software, then spinlocks might be the solution. This is
> assuming you know exactly what you are doing (but in that case you would
> not need help from strangers in internet).

Spin-Locks are Locks with unlimted spinning, and this doesn't make
sense in userspace since the thread holding the lock can't disable
the scheduler so that it can't be scheduled away. This is necessary
because a thread spinning for a lock where the holder is scheduled
away can take extemely long.
Under Windows there are two types of spinlocks in kernel-space. One
type disables the scheduler only while holding the lock, the other
type is the so called interrupt spinlock, where the interrupt-level
on that core is raised to a specified level that a thread can compete
for resources with an interrupt, thereby disabling the interrupt.

So forget about using spinlocks in userspace !

Frederick Virchanza Gotham

unread,
Jul 24, 2022, 12:20:09 PM7/24/22
to
On Sunday, July 24, 2022 at 4:40:54 PM UTC+1, Bonita Montero wrote:
>
> Spin-Locks are Locks with unlimted spinning <snip>


I need to clarify something here. I'm not sure if we're using the same terminology. When I say 'spin lock', what I mean is just checking an atomic variable in a loop. Something like as follows:

atomic<bool> g_should_process_data = false;

void Entry_Point_For_Worker_Thread(void)
{
for (;;)
{
while ( false == g_should_process_data ); // <-- This is what I mean when I say 'spin lock'

/* Process data */
}
}

int main(void)
{
thread t(Entry_Point_For_Worker_Thread);

for (;;)
{
g_should_process_data = true;

/* Do some other stuff */
}
}

I'm not sure if you mean something else by "spin lock".

Paavo Helde

unread,
Jul 24, 2022, 12:34:22 PM7/24/22
to
24.07.2022 19:20 Frederick Virchanza Gotham kirjutas:
> On Sunday, July 24, 2022 at 4:40:54 PM UTC+1, Bonita Montero wrote:
>>
>> Spin-Locks are Locks with unlimted spinning <snip>
>
>
> I need to clarify something here. I'm not sure if we're using the same terminology. When I say 'spin lock', what I mean is just checking an atomic variable in a loop.

That would be a user-space spinlock which Bonita is talking about.

>
> I'm not sure if you mean something else by "spin lock".

I was assuming you are using something like pthread_spin_lock()
(https://man7.org/linux/man-pages/man3/pthread_spin_lock.3.html).



Bonita Montero

unread,
Jul 24, 2022, 12:56:35 PM7/24/22
to
Am 24.07.2022 um 18:20 schrieb Frederick Virchanza Gotham:
> On Sunday, July 24, 2022 at 4:40:54 PM UTC+1, Bonita Montero wrote:
>>
>> Spin-Locks are Locks with unlimted spinning <snip>
>
>
> I need to clarify something here. I'm not sure if we're using the same terminology. When I say 'spin lock', what I mean is just checking an atomic variable in a loop. Something like as follows:

https://stackoverflow.com/questions/14723924/using-spinlocks-in-user-space-application

Bonita Montero

unread,
Jul 24, 2022, 1:00:31 PM7/24/22
to
I forget to mention: really enjoying to have such discussions here
without Pete Olcott in the rhread. He is still dealing with the more
important issues. ;-)

Keith Thompson

unread,
Jul 24, 2022, 2:39:08 PM7/24/22
to
Frederick Virchanza Gotham <cauldwel...@gmail.com> writes:
[...]
> void Entry_Point_For_Worker_Thread(void)
> {
> for (;;)
> {
> while ( false == g_should_process_data ); // <-- This is what I mean when I say 'spin lock'
>
> /* Process data */
> }
> }
[...]

Not relevant to your question, but why would you write
`false == g_should_process_data` rather than `! should_process_data`?

--
Keith Thompson (The_Other_Keith) Keith.S.T...@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */

Chris M. Thomasson

unread,
Jul 24, 2022, 4:17:44 PM7/24/22
to
On 7/24/2022 9:20 AM, Frederick Virchanza Gotham wrote:
> On Sunday, July 24, 2022 at 4:40:54 PM UTC+1, Bonita Montero wrote:
>>
>> Spin-Locks are Locks with unlimted spinning <snip>
>
>
> I need to clarify something here. I'm not sure if we're using the same terminology. When I say 'spin lock', what I mean is just checking an atomic variable in a loop. Something like as follows:
>
> atomic<bool> g_should_process_data = false;
>
> void Entry_Point_For_Worker_Thread(void)
> {
> for (;;)
> {
> while ( false == g_should_process_data ); // <-- This is what I mean when I say 'spin lock'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Yikes! You really should have a backoff in there. Do you want your
worker threads to be running full speed with absolutely nothing to do?

Chris M. Thomasson

unread,
Jul 24, 2022, 4:20:28 PM7/24/22
to
A main thread with multiple worker threads sounds like a great place for
a single-producer/multi-consumer queue. If you are interested in sheer
performance, there are several interesting options. Perhaps I can help
you. Do you care if you get FIFO, or LIFO?

Chris M. Thomasson

unread,
Jul 24, 2022, 7:55:35 PM7/24/22
to
Oh. Reading your original thread.

Öö Tiib

unread,
Jul 25, 2022, 6:21:16 AM7/25/22
to
On Sunday, 24 July 2022 at 23:17:44 UTC+3, Chris M. Thomasson wrote:
> On 7/24/2022 9:20 AM, Frederick Virchanza Gotham wrote:
> > On Sunday, July 24, 2022 at 4:40:54 PM UTC+1, Bonita Montero wrote:
> >>
> >> Spin-Locks are Locks with unlimted spinning <snip>
> >
> >
> > I need to clarify something here. I'm not sure if we're using the same terminology. When I say 'spin lock', what I mean is just checking an atomic variable in a loop. Something like as follows:
> >
> > atomic<bool> g_should_process_data = false;
> >
> > void Entry_Point_For_Worker_Thread(void)
> > {
> > for (;;)
> > {
> > while ( false == g_should_process_data ); // <-- This is what I mean when I say 'spin lock'
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> Yikes! You really should have a backoff in there. Do you want your
> worker threads to be running full speed with absolutely nothing to do?

Yes. Whatever spinlock should be held for rather short time. Here we are
misnaming infinitely busy poll loop (that is terrible anti-pattern) as
"spinlock".

The symptoms from OP that "CPU fan getting a bit load and the OS
getting a big laggy" are because one of cores is full busy warming room.
It is visible in whatever activity monitor or task manager of operating
system and anyone half-savvy suggests to kill and uninstall it right away.
0 new messages