Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #120424 > unrolled thread

a try_lock pattern...

Started by"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
First post2024-09-28 00:20 -0700
Last post2024-09-29 12:58 -0700
Articles 20 on this page of 46 — 5 participants

Back to article view | Back to comp.lang.c++


Contents

  a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-28 00:20 -0700
    Re: a try_lock pattern... Paavo Helde <eesnimi@osa.pri.ee> - 2024-09-28 10:53 +0300
      Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-28 12:18 -0700
        Re: a try_lock pattern... scott@slp53.sl.home (Scott Lurndal) - 2024-09-29 18:03 +0000
          Re: a try_lock pattern... Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-29 20:15 +0200
            Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-29 13:18 -0700
              Re: a try_lock pattern... Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-30 07:53 +0200
                Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-30 16:41 -0700
                  Re: a try_lock pattern... Bonita Montero <Bonita.Montero@gmail.com> - 2024-10-01 06:45 +0200
                    Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-10-01 11:44 -0700
                      Re: a try_lock pattern... Bonita Montero <Bonita.Montero@gmail.com> - 2024-10-01 21:40 +0200
                        Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-10-01 12:48 -0700
          Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-29 12:55 -0700
    Re: a try_lock pattern... Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-28 10:40 +0200
      Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-28 12:55 -0700
        Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-28 16:30 -0700
          Re: a try_lock pattern... Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-29 08:15 +0200
            Re: a try_lock pattern... Muttley@dastardlyhq.com - 2024-09-29 09:01 +0000
              Re: a try_lock pattern... Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-29 12:54 +0200
                Re: a try_lock pattern... Muttley@dastardlyhq.com - 2024-09-29 14:56 +0000
                  Re: a try_lock pattern... Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-29 17:20 +0200
                    Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-29 13:24 -0700
                      Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-29 14:03 -0700
                      Re: a try_lock pattern... Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-30 07:51 +0200
                        Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-10-01 12:34 -0700
                          Re: a try_lock pattern... Bonita Montero <Bonita.Montero@gmail.com> - 2024-10-02 00:58 +0200
                    Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-29 14:45 -0700
                      Re: a try_lock pattern... Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-30 07:52 +0200
                        Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-30 18:11 -0700
                          Re: a try_lock pattern... Bonita Montero <Bonita.Montero@gmail.com> - 2024-10-01 06:47 +0200
                            Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-10-01 11:45 -0700
                      Re: a try_lock pattern... Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-30 08:02 +0200
                        Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-30 16:37 -0700
                          Re: a try_lock pattern... Bonita Montero <Bonita.Montero@gmail.com> - 2024-10-01 09:17 +0200
                            Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-10-01 11:49 -0700
                              Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-10-01 12:37 -0700
                              Re: a try_lock pattern... Bonita Montero <Bonita.Montero@gmail.com> - 2024-10-02 01:30 +0200
                                Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-10-01 16:37 -0700
                                  Re: a try_lock pattern... Bonita Montero <Bonita.Montero@gmail.com> - 2024-10-02 01:43 +0200
                                    Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-10-01 18:20 -0700
                                      Re: a try_lock pattern... Bonita Montero <Bonita.Montero@gmail.com> - 2024-10-02 03:24 +0200
                                        Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-10-01 18:25 -0700
                                          Re: a try_lock pattern... Bonita Montero <Bonita.Montero@gmail.com> - 2024-10-02 04:13 +0200
                                            Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-10-02 16:57 -0700
                  Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-29 19:53 -0700
              Re: a try_lock pattern... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-29 12:58 -0700

Page 1 of 3  [1] 2 3  Next page →


#120424 — a try_lock pattern...

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2024-09-28 00:20 -0700
Subjecta try_lock pattern...
Message-ID<vd8an7$15ff9$1@dont-email.me>
This is just a quick test of my try_lock pattern thing. ct_shared::m_b 
counts how many times extra work was able to be done instead of spinning 
on the ct_shared::m_lock_a mutex. Take careful notice of the 
ct_shared::work_a_lock() function.

Can you test it out? A large number for ct_shared::m_b is ideal. It 
means extra work was being done. Avoids spinning in an interesting way.

my crude code, can you compile and run it okay? Thanks:
_________________________
#include <cassert>
#include <iostream>
#include <atomic>
#include <mutex>
#include <functional>
#include <thread>


#define CT_THREADS 10
#define CT_ITERS 1000000


// Test Threads...
struct ct_shared
{
     long m_a;
     unsigned long m_b;
     std::mutex m_lock_a;
     std::mutex m_lock_b;

     ct_shared() : m_a(0), m_b(0) {}


     bool work_b_try(unsigned long addend)
     {
         if (! m_lock_b.try_lock())
         {
             return false;
         }

         {
             m_b += addend;
         }

         m_lock_b.unlock();

         return true;
     }

     // The main pattern...
     void work_a_lock()
     {
         while (! m_lock_a.try_lock())
         {
             if (! work_b_try(1))
             {
                 m_lock_a.lock();
                 break;
             }
         }
     }

     void work_a_unlock()
     {
         m_lock_a.unlock();
     }

     void work_a(long addend)
     {
         work_a_lock();

         {
             m_a += addend;
         }

         work_a_unlock();
     }
};


// Test out a pattern...
void
ct_thread(
     ct_shared& shared
) {
     for (unsigned long i = 0; i < CT_ITERS; ++i)
     {
         shared.work_a(1);
         std::this_thread::yield();
         shared.work_a(-1);
     }
}


// Get things going...
int
main()
{
     std::cout << "ct try_lock pattern Test...\n\n";

     {
         ct_shared shared;

         std::thread threads[CT_THREADS];

         // Create threads...
         std::cout << "launching threads..." << std::endl;

         for (unsigned long i = 0; i < CT_THREADS; ++i)
         {
             threads[i] = std::thread(ct_thread, std::ref(shared));

         }

         std::cout << "processing...\n" << std::endl;

         // Join threads...
         for (unsigned long i = 0; i < CT_THREADS; ++i)
         {
             threads[i].join();
         }

         // Sanity check...
         {
             std::cout << "shared.m_a = " << shared.m_a << "\n";
             std::cout << "shared.m_b = " << shared.m_b << "\n";

             if (shared.m_a != 0)
             {
                 std::cout << "\n\nAAHHHH SHHHIIITT!!\n";
             }

         }
     }

     std::cout << "\nct try_lock pattern Test completed.\n\n";

     return 0;
}
_________________________


What results do you get for ct_shared::m_b? Here is a result I get:
_____________________________
ct try_lock pattern Test...

launching threads...
processing...

shared.m_a = 0
shared.m_b = 8664093

ct try_lock pattern Test completed.
_____________________________

Well, shared.m_b is a high number... That is a lot potential kernel 
calls that were skipped in favor of real work.

Any thoughts? Thanks.

[toc] | [next] | [standalone]


#120426

FromPaavo Helde <eesnimi@osa.pri.ee>
Date2024-09-28 10:53 +0300
Message-ID<vd8cmd$159kt$3@dont-email.me>
In reply to#120424
On 28.09.2024 10:20, Chris M. Thomasson wrote:
> This is just a quick test of my try_lock pattern thing. ct_shared::m_b 
> counts how many times extra work was able to be done instead of spinning 
> on the ct_shared::m_lock_a mutex. Take careful notice of the 
> ct_shared::work_a_lock() function.
> 
> Can you test it out? A large number for ct_shared::m_b is ideal. It 
> means extra work was being done. Avoids spinning in an interesting way.
> 
> my crude code, can you compile and run it okay? Thanks:
> _________________________
> #include <cassert>
> #include <iostream>
> #include <atomic>
> #include <mutex>
> #include <functional>
> #include <thread>
> 
> 
> #define CT_THREADS 10
> #define CT_ITERS 1000000
> 
> 
> // Test Threads...
> struct ct_shared
> {
>      long m_a;
>      unsigned long m_b;
>      std::mutex m_lock_a;
>      std::mutex m_lock_b;
> 
>      ct_shared() : m_a(0), m_b(0) {}
> 
> 
>      bool work_b_try(unsigned long addend)
>      {
>          if (! m_lock_b.try_lock())
>          {
>              return false;
>          }
> 
>          {
>              m_b += addend;
>          }
> 
>          m_lock_b.unlock();
> 
>          return true;
>      }
> 
>      // The main pattern...
>      void work_a_lock()
>      {
>          while (! m_lock_a.try_lock())
>          {
>              if (! work_b_try(1))
>              {
>                  m_lock_a.lock();
>                  break;
>              }
>          }
>      }
> 
>      void work_a_unlock()
>      {
>          m_lock_a.unlock();
>      }
> 
>      void work_a(long addend)
>      {
>          work_a_lock();
> 
>          {
>              m_a += addend;
>          }
> 
>          work_a_unlock();
>      }
> };
> 
> 
> // Test out a pattern...
> void
> ct_thread(
>      ct_shared& shared
> ) {
>      for (unsigned long i = 0; i < CT_ITERS; ++i)
>      {
>          shared.work_a(1);
>          std::this_thread::yield();
>          shared.work_a(-1);
>      }
> }
> 
> 
> // Get things going...
> int
> main()
> {
>      std::cout << "ct try_lock pattern Test...\n\n";
> 
>      {
>          ct_shared shared;
> 
>          std::thread threads[CT_THREADS];
> 
>          // Create threads...
>          std::cout << "launching threads..." << std::endl;
> 
>          for (unsigned long i = 0; i < CT_THREADS; ++i)
>          {
>              threads[i] = std::thread(ct_thread, std::ref(shared));
> 
>          }
> 
>          std::cout << "processing...\n" << std::endl;
> 
>          // Join threads...
>          for (unsigned long i = 0; i < CT_THREADS; ++i)
>          {
>              threads[i].join();
>          }
> 
>          // Sanity check...
>          {
>              std::cout << "shared.m_a = " << shared.m_a << "\n";
>              std::cout << "shared.m_b = " << shared.m_b << "\n";
> 
>              if (shared.m_a != 0)
>              {
>                  std::cout << "\n\nAAHHHH SHHHIIITT!!\n";
>              }
> 
>          }
>      }
> 
>      std::cout << "\nct try_lock pattern Test completed.\n\n";
> 
>      return 0;
> }
> _________________________
> 
> 
> What results do you get for ct_shared::m_b? Here is a result I get:
> _____________________________
> ct try_lock pattern Test...
> 
> launching threads...
> processing...
> 
> shared.m_a = 0
> shared.m_b = 8664093
> 
> ct try_lock pattern Test completed.
> _____________________________
> 
> Well, shared.m_b is a high number... That is a lot potential kernel 
> calls that were skipped in favor of real work.
> 
> Any thoughts? Thanks.

Seems to compile and work fine with VS2022 on Windows x86_64

ct try_lock pattern Test...

launching threads...
processing...

shared.m_a = 0
shared.m_b = 6976047

ct try_lock pattern Test completed.

[toc] | [prev] | [next] | [standalone]


#120437

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2024-09-28 12:18 -0700
Message-ID<vd9kph$1c8ti$1@dont-email.me>
In reply to#120426
On 9/28/2024 12:53 AM, Paavo Helde wrote:
> On 28.09.2024 10:20, Chris M. Thomasson wrote:
>> This is just a quick test of my try_lock pattern thing. ct_shared::m_b 
>> counts how many times extra work was able to be done instead of 
>> spinning on the ct_shared::m_lock_a mutex. Take careful notice of the 
>> ct_shared::work_a_lock() function.
>>
>> Can you test it out? A large number for ct_shared::m_b is ideal. It 
>> means extra work was being done. Avoids spinning in an interesting way.
>>
>> my crude code, can you compile and run it okay? Thanks:
>> _________________________

[...]

>> _________________________
>>
>>
>> What results do you get for ct_shared::m_b? Here is a result I get:
>> _____________________________
>> ct try_lock pattern Test...
>>
>> launching threads...
>> processing...
>>
>> shared.m_a = 0
>> shared.m_b = 8664093
>>
>> ct try_lock pattern Test completed.
>> _____________________________
>>
>> Well, shared.m_b is a high number... That is a lot potential kernel 
>> calls that were skipped in favor of real work.
>>
>> Any thoughts? Thanks.
> 
> Seems to compile and work fine with VS2022 on Windows x86_64

Nice! Thanks for taking the time to give it a go Paavo. Basically, the 
main "pattern" is in the ct_shared::work_a_lock() function:
_____________________
void work_a_lock()
{
     while (! m_lock_a.try_lock())
     {
         if (! work_b_try(1))
         {
             m_lock_a.lock();
             break;
         }
     }
}
_____________________

If the m_lock_a.try_lock() fails, we know the lock is contended. So, why 
not try to do some other work ala work_b_try(1)? If the work_b got to do 
something useful, we do not need to block for m_lock_a. We can _try_ to 
lock it again. If work_b_try fails to do any work, we simply commit and 
block on m_lock_a via m_lock_a.lock() instead of try_lock().

This pattern is interesting to me.


> ct try_lock pattern Test...
> 
> launching threads...
> processing...
> 
> shared.m_a = 0
> shared.m_b = 6976047
> 
> ct try_lock pattern Test completed.
> 
> 

So, real work wrt work_b was performed 6976047 times in this run. This 
is good because it means actual work was done while m_lock_a was contended.

Make any sense to you? Thanks again Paavo.

[toc] | [prev] | [next] | [standalone]


#120454

Fromscott@slp53.sl.home (Scott Lurndal)
Date2024-09-29 18:03 +0000
Message-ID<ODgKO.253710$FzW1.65557@fx14.iad>
In reply to#120437
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> writes:
>On 9/28/2024 12:53 AM, Paavo Helde wrote:

>Nice! Thanks for taking the time to give it a go Paavo. Basically, the 
>main "pattern" is in the ct_shared::work_a_lock() function:
>_____________________
>void work_a_lock()
>{
>     while (! m_lock_a.try_lock())
>     {
>         if (! work_b_try(1))
>         {
>             m_lock_a.lock();
>             break;
>         }
>     }
>}
>_____________________
>

Seems a waste.  Just fire up two threads one for b work
and one for a work.   Let the OS manage the CPUs.

[toc] | [prev] | [next] | [standalone]


#120455

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-29 20:15 +0200
Message-ID<vdc5g7$1rc8c$1@raubtier-asyl.eternal-september.org>
In reply to#120454
Am 29.09.2024 um 20:03 schrieb Scott Lurndal:

> Seems a waste.  Just fire up two threads one for b work
> and one for a work.   Let the OS manage the CPUs.

That's what I also thought but he thinks there are tiny tasks
which you can do optionally. But these are never expendable.

[toc] | [prev] | [next] | [standalone]


#120459

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2024-09-29 13:18 -0700
Message-ID<vdccn8$1s42m$3@dont-email.me>
In reply to#120455
On 9/29/2024 11:15 AM, Bonita Montero wrote:
> Am 29.09.2024 um 20:03 schrieb Scott Lurndal:
> 
>> Seems a waste.  Just fire up two threads one for b work
>> and one for a work.   Let the OS manage the CPUs.
> 
> That's what I also thought but he thinks there are tiny tasks
> which you can do optionally. But these are never expendable.
> 

The tiny, or not so tiny, tasks are meant to act like a sort of 
"backoff", in a sense. Think about an adaptive mutex that spins (doing 
nothing) in user space before it calls into the kernel for an actual 
wait on a contended mutex (very slow path). Well, what if each spin was 
getting work done instead of spinning for no work at all, just waiting 
for the contended lock to be unlocked... I need to create another test.

[toc] | [prev] | [next] | [standalone]


#120467

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-30 07:53 +0200
Message-ID<vddecg$24evr$3@raubtier-asyl.eternal-september.org>
In reply to#120459
Am 29.09.2024 um 22:18 schrieb Chris M. Thomasson:
> On 9/29/2024 11:15 AM, Bonita Montero wrote:
>> Am 29.09.2024 um 20:03 schrieb Scott Lurndal:
>>
>>> Seems a waste.  Just fire up two threads one for b work
>>> and one for a work.   Let the OS manage the CPUs.
>>
>> That's what I also thought but he thinks there are tiny tasks
>> which you can do optionally. But these are never expendable.
>>
> 
> The tiny, or not so tiny, tasks are meant to act like a sort of 
> "backoff", in a sense. Think about an adaptive mutex that spins (doing 
> nothing) in user space before it calls into the kernel for an actual 
> wait on a contended mutex (very slow path). Well, what if each spin was 
> getting work done instead of spinning for no work at all, just waiting 
> for the contended lock to be unlocked... I need to create another test.

That's not a practical example but just how it basically works.

[toc] | [prev] | [next] | [standalone]


#120484

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2024-09-30 16:41 -0700
Message-ID<vdfcvr$2e018$2@dont-email.me>
In reply to#120467
On 9/29/2024 10:53 PM, Bonita Montero wrote:
> Am 29.09.2024 um 22:18 schrieb Chris M. Thomasson:
>> On 9/29/2024 11:15 AM, Bonita Montero wrote:
>>> Am 29.09.2024 um 20:03 schrieb Scott Lurndal:
>>>
>>>> Seems a waste.  Just fire up two threads one for b work
>>>> and one for a work.   Let the OS manage the CPUs.
>>>
>>> That's what I also thought but he thinks there are tiny tasks
>>> which you can do optionally. But these are never expendable.
>>>
>>
>> The tiny, or not so tiny, tasks are meant to act like a sort of 
>> "backoff", in a sense. Think about an adaptive mutex that spins (doing 
>> nothing) in user space before it calls into the kernel for an actual 
>> wait on a contended mutex (very slow path). Well, what if each spin 
>> was getting work done instead of spinning for no work at all, just 
>> waiting for the contended lock to be unlocked... I need to create 
>> another test.
> 
> That's not a practical example but just how it basically works.

Sigh... One more time:

Instead of a thread spinning doing nothing waiting on a contended 
lock... Well, why not try to do some work? This is _very_ different than 
spinning doing absolutely nothing at all! Right? ;^o

Actually, it reminds me of a special case of work stealing in a sense... 
That is almost another topic...

[toc] | [prev] | [next] | [standalone]


#120486

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-10-01 06:45 +0200
Message-ID<vdfuov$2jthm$1@raubtier-asyl.eternal-september.org>
In reply to#120484
Am 01.10.2024 um 01:41 schrieb Chris M. Thomasson:
> On 9/29/2024 10:53 PM, Bonita Montero wrote:
>> Am 29.09.2024 um 22:18 schrieb Chris M. Thomasson:
>>> On 9/29/2024 11:15 AM, Bonita Montero wrote:
>>>> Am 29.09.2024 um 20:03 schrieb Scott Lurndal:
>>>>
>>>>> Seems a waste.  Just fire up two threads one for b work
>>>>> and one for a work.   Let the OS manage the CPUs.
>>>>
>>>> That's what I also thought but he thinks there are tiny tasks
>>>> which you can do optionally. But these are never expendable.
>>>>
>>>
>>> The tiny, or not so tiny, tasks are meant to act like a sort of 
>>> "backoff", in a sense. Think about an adaptive mutex that spins 
>>> (doing nothing) in user space before it calls into the kernel for an 
>>> actual wait on a contended mutex (very slow path). Well, what if each 
>>> spin was getting work done instead of spinning for no work at all, 
>>> just waiting for the contended lock to be unlocked... I need to 
>>> create another test.
>>
>> That's not a practical example but just how it basically works.
> 
> Sigh... One more time:
> 
> Instead of a thread spinning doing nothing waiting on a contended 
> lock... Well, why not try to do some work? This is _very_ different than 
> spinning doing absolutely nothing at all! Right? ;^o

That's still not a practical example but just how it technically
works.

> Actually, it reminds me of a special case of work stealing in a sense... 
> That is almost another topic...

[toc] | [prev] | [next] | [standalone]


#120517

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2024-10-01 11:44 -0700
Message-ID<vdhfuq$2rfgp$2@dont-email.me>
In reply to#120486
On 9/30/2024 9:45 PM, Bonita Montero wrote:
> Am 01.10.2024 um 01:41 schrieb Chris M. Thomasson:
>> On 9/29/2024 10:53 PM, Bonita Montero wrote:
>>> Am 29.09.2024 um 22:18 schrieb Chris M. Thomasson:
>>>> On 9/29/2024 11:15 AM, Bonita Montero wrote:
>>>>> Am 29.09.2024 um 20:03 schrieb Scott Lurndal:
>>>>>
>>>>>> Seems a waste.  Just fire up two threads one for b work
>>>>>> and one for a work.   Let the OS manage the CPUs.
>>>>>
>>>>> That's what I also thought but he thinks there are tiny tasks
>>>>> which you can do optionally. But these are never expendable.
>>>>>
>>>>
>>>> The tiny, or not so tiny, tasks are meant to act like a sort of 
>>>> "backoff", in a sense. Think about an adaptive mutex that spins 
>>>> (doing nothing) in user space before it calls into the kernel for an 
>>>> actual wait on a contended mutex (very slow path). Well, what if 
>>>> each spin was getting work done instead of spinning for no work at 
>>>> all, just waiting for the contended lock to be unlocked... I need to 
>>>> create another test.
>>>
>>> That's not a practical example but just how it basically works.

It shows how try_lock can be used to try to avoid a spin that does 
nothing at all. Keep in mind that a spin in the traditional sense means 
the thread is doing no work at all. My, imvvvho, fun and experimental 
thing means that a spin actually accomplished some real work.



>>
>> Sigh... One more time:
>>
>> Instead of a thread spinning doing nothing waiting on a contended 
>> lock... Well, why not try to do some work? This is _very_ different 
>> than spinning doing absolutely nothing at all! Right? ;^o
> 
> That's still not a practical example but just how it technically
> works.
> 
>> Actually, it reminds me of a special case of work stealing in a 
>> sense... That is almost another topic...
> 

[toc] | [prev] | [next] | [standalone]


#120523

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-10-01 21:40 +0200
Message-ID<vdhj6r$2s108$1@raubtier-asyl.eternal-september.org>
In reply to#120517
Am 01.10.2024 um 20:44 schrieb Chris M. Thomasson:
> On 9/30/2024 9:45 PM, Bonita Montero wrote:
>> Am 01.10.2024 um 01:41 schrieb Chris M. Thomasson:
>>> On 9/29/2024 10:53 PM, Bonita Montero wrote:
>>>> Am 29.09.2024 um 22:18 schrieb Chris M. Thomasson:
>>>>> On 9/29/2024 11:15 AM, Bonita Montero wrote:
>>>>>> Am 29.09.2024 um 20:03 schrieb Scott Lurndal:
>>>>>>
>>>>>>> Seems a waste.  Just fire up two threads one for b work
>>>>>>> and one for a work.   Let the OS manage the CPUs.
>>>>>>
>>>>>> That's what I also thought but he thinks there are tiny tasks
>>>>>> which you can do optionally. But these are never expendable.
>>>>>>
>>>>>
>>>>> The tiny, or not so tiny, tasks are meant to act like a sort of 
>>>>> "backoff", in a sense. Think about an adaptive mutex that spins 
>>>>> (doing nothing) in user space before it calls into the kernel for 
>>>>> an actual wait on a contended mutex (very slow path). Well, what if 
>>>>> each spin was getting work done instead of spinning for no work at 
>>>>> all, just waiting for the contended lock to be unlocked... I need 
>>>>> to create another test.
>>>>
>>>> That's not a practical example but just how it basically works.
> 
> It shows how try_lock can be used to try to avoid a spin that does 
> nothing at all. Keep in mind that a spin in the traditional sense means 
> the thread is doing no work at all. My, imvvvho, fun and experimental 
> thing means that a spin actually accomplished some real work.

Stil no pracical example.

[toc] | [prev] | [next] | [standalone]


#120524

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2024-10-01 12:48 -0700
Message-ID<vdhjmn$2rfd8$3@dont-email.me>
In reply to#120523
On 10/1/2024 12:40 PM, Bonita Montero wrote:
> Am 01.10.2024 um 20:44 schrieb Chris M. Thomasson:
>> On 9/30/2024 9:45 PM, Bonita Montero wrote:
>>> Am 01.10.2024 um 01:41 schrieb Chris M. Thomasson:
>>>> On 9/29/2024 10:53 PM, Bonita Montero wrote:
>>>>> Am 29.09.2024 um 22:18 schrieb Chris M. Thomasson:
>>>>>> On 9/29/2024 11:15 AM, Bonita Montero wrote:
>>>>>>> Am 29.09.2024 um 20:03 schrieb Scott Lurndal:
>>>>>>>
>>>>>>>> Seems a waste.  Just fire up two threads one for b work
>>>>>>>> and one for a work.   Let the OS manage the CPUs.
>>>>>>>
>>>>>>> That's what I also thought but he thinks there are tiny tasks
>>>>>>> which you can do optionally. But these are never expendable.
>>>>>>>
>>>>>>
>>>>>> The tiny, or not so tiny, tasks are meant to act like a sort of 
>>>>>> "backoff", in a sense. Think about an adaptive mutex that spins 
>>>>>> (doing nothing) in user space before it calls into the kernel for 
>>>>>> an actual wait on a contended mutex (very slow path). Well, what 
>>>>>> if each spin was getting work done instead of spinning for no work 
>>>>>> at all, just waiting for the contended lock to be unlocked... I 
>>>>>> need to create another test.
>>>>>
>>>>> That's not a practical example but just how it basically works.
>>
>> It shows how try_lock can be used to try to avoid a spin that does 
>> nothing at all. Keep in mind that a spin in the traditional sense 
>> means the thread is doing no work at all. My, imvvvho, fun and 
>> experimental thing means that a spin actually accomplished some real 
>> work.
> 
> Stil no pracical example.
> 

Yawn.

[toc] | [prev] | [next] | [standalone]


#120457

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2024-09-29 12:55 -0700
Message-ID<vdcbc6$1s42m$1@dont-email.me>
In reply to#120454
On 9/29/2024 11:03 AM, Scott Lurndal wrote:
> "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> writes:
>> On 9/28/2024 12:53 AM, Paavo Helde wrote:
> 
>> Nice! Thanks for taking the time to give it a go Paavo. Basically, the
>> main "pattern" is in the ct_shared::work_a_lock() function:
>> _____________________
>> void work_a_lock()
>> {
>>      while (! m_lock_a.try_lock())
>>      {
>>          if (! work_b_try(1))
>>          {
>>              m_lock_a.lock();
>>              break;
>>          }
>>      }
>> }
>> _____________________
>>
> 
> Seems a waste.  Just fire up two threads one for b work
> and one for a work.   Let the OS manage the CPUs.

Creating only two threads, one for work_a and one for work_b would mean 
that I would not even have to use any mutexes because it would be 
embarrassingly parallel.

Humm... I am not quite sure if its a total waste or not. The idea is to 
try to to do some work_b instead of potentially waiting in the kernel 
for work_a while its in a contended state. Actually, for some reason, it 
kind of reminds me of work stealing. A contended work_a can try to steal 
some of work_b's workload. Humm... Once work_a is contended, what should 
the thread do in the mean time?

[toc] | [prev] | [next] | [standalone]


#120427

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-28 10:40 +0200
Message-ID<vd8fcv$163g3$1@raubtier-asyl.eternal-september.org>
In reply to#120424
You still not show a practical sample of a situation where a) the
locking is allowed to be delayed an arbitrary time and b) the work
you'd do when locking fails can happen never since locking always
succeds. These both constraints do not leave much space for practi-
cal examlpes.

[toc] | [prev] | [next] | [standalone]


#120438

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2024-09-28 12:55 -0700
Message-ID<vd9n05$1c8ti$2@dont-email.me>
In reply to#120427
On 9/28/2024 1:40 AM, Bonita Montero wrote:
> You still not show a practical sample of a situation where a) the
> locking is allowed to be delayed an arbitrary time and b) the work
> you'd do when locking fails can happen never since locking always
> succeds. 

You mean work_b being starved out? Well, you are missing the point that 
course somebody can lock work_b's mutex and get work done. The try_lock 
pattern is being focused on work_a.



> These both constraints do not leave much space for practi-
> cal examlpes.
> 

[toc] | [prev] | [next] | [standalone]


#120441

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2024-09-28 16:30 -0700
Message-ID<vda3i3$1ego6$1@dont-email.me>
In reply to#120438
On 9/28/2024 12:55 PM, Chris M. Thomasson wrote:
> On 9/28/2024 1:40 AM, Bonita Montero wrote:
>> You still not show a practical sample of a situation where a) the
>> locking is allowed to be delayed an arbitrary time and b) the work
>> you'd do when locking fails can happen never since locking always
>> succeds. 
> 
> You mean work_b being starved out? Well, you are missing the point that 
> course somebody can lock work_b's mutex and get work done. The try_lock 
> pattern is being focused on work_a.

Actually, Bonita. You made me think of adding another counter to work_b. 
One that records how many times it was worked on in a contended m_lock_a 
try_lock condition vs one where another thread locks and unlocks 
m_lock_b that is in charge of work_b. Humm... A contended m_lock_a means 
work_b can be tried.



> 
> 
> 
>> These both constraints do not leave much space for practi-
>> cal examlpes.
>>
> 

[toc] | [prev] | [next] | [standalone]


#120442

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-29 08:15 +0200
Message-ID<vdar9i$1l8u6$1@raubtier-asyl.eternal-september.org>
In reply to#120441
Am 29.09.2024 um 01:30 schrieb Chris M. Thomasson:
> On 9/28/2024 12:55 PM, Chris M. Thomasson wrote:
>> On 9/28/2024 1:40 AM, Bonita Montero wrote:
>>> You still not show a practical sample of a situation where a) the
>>> locking is allowed to be delayed an arbitrary time and b) the work
>>> you'd do when locking fails can happen never since locking always
>>> succeds. 
>>
>> You mean work_b being starved out? Well, you are missing the point 
>> that course somebody can lock work_b's mutex and get work done. The 
>> try_lock pattern is being focused on work_a.
> 
> Actually, Bonita. You made me think of adding another counter to work_b. 
> One that records how many times it was worked on in a contended m_lock_a 
> try_lock condition vs one where another thread locks and unlocks 
> m_lock_b that is in charge of work_b. Humm... A contended m_lock_a means 
> work_b can be tried.

You're focussed on details that you don't see the whole picture and
you're telling nonsense. Try to find some code of someone who uses
try_lock in that way on GitHub; you won't find code like this. No
one uses try_lock.

[toc] | [prev] | [next] | [standalone]


#120443

FromMuttley@dastardlyhq.com
Date2024-09-29 09:01 +0000
Message-ID<vdb51u$1mmu7$1@dont-email.me>
In reply to#120442
On Sun, 29 Sep 2024 08:15:23 +0200
Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>try_lock in that way on GitHub; you won't find code like this. No
>one uses try_lock.

Translation: "I don't use try_lock"

[toc] | [prev] | [next] | [standalone]


#120444

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-29 12:54 +0200
Message-ID<vdbbl5$1nm58$1@raubtier-asyl.eternal-september.org>
In reply to#120443
Am 29.09.2024 um 11:01 schrieb Muttley@dastardlyhq.com:
> On Sun, 29 Sep 2024 08:15:23 +0200
> Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>> try_lock in that way on GitHub; you won't find code like this. No
>> one uses try_lock.
> 
> Translation: "I don't use try_lock"

Tell me under which circumstances the mentioned two constraints
don't matter.

[toc] | [prev] | [next] | [standalone]


#120451

FromMuttley@dastardlyhq.com
Date2024-09-29 14:56 +0000
Message-ID<vdbpqr$1pkc1$1@dont-email.me>
In reply to#120444
On Sun, 29 Sep 2024 12:54:38 +0200
Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>Am 29.09.2024 um 11:01 schrieb Muttley@dastardlyhq.com:
>> On Sun, 29 Sep 2024 08:15:23 +0200
>> Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>>> try_lock in that way on GitHub; you won't find code like this. No
>>> one uses try_lock.
>> 
>> Translation: "I don't use try_lock"
>
>Tell me under which circumstances the mentioned two constraints
>don't matter.

Don't know, don't care. But I can imagine a number of scenarios where 
someone might use try_lock when they don't want the thread to hang but go
do something more useful instead if it can't obtain a lock.

[toc] | [prev] | [next] | [standalone]


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | comp.lang.c++


csiph-web