0

I have some C code (on Linux) that needs to run in a thread safe manner. It's very low contention but I have to guard it to ensure correctness.

I have the option of using local variables to guard it (which will work based on how the code is written) but since I have a mutex variable, which is the better approach in terms of cpu usage?

As I expect nearly never to have any contention on the lock is acquiring and releasing mutex significantly more costly compared to checking, incrementing and decrementing a local variable ?

I use the mutex elsewhere so by not using it I am not saving any memory.

Severin Pappadeux
  • 18,636
  • 3
  • 38
  • 64
L Lawliet
  • 2,565
  • 4
  • 26
  • 35
  • 1
    What platform? For example, on Linux with mutex being implemented via futex, there is no context switch if mutex is not contended – Severin Pappadeux Jul 08 '16 at 02:38
  • 3
    "I have the option of using local variables to guard it (which will work based on how the code is written)" - that sounds extremely unlikely. – user2357112 Jul 08 '16 at 02:41
  • 1
    Well, in uncontested case mutex/futex amounts to cmpxchgXX() on address in user space - reasonable cheap, and basically if you use local atomic, it would have about the same cost. In contested case it does require kernel support for queue lookup and waking up another thread, and you cannot do that with any local atomics anyway – Severin Pappadeux Jul 08 '16 at 02:46
  • Not for every day use, but depending on circumstances, I would also consider a spin-lock. Do notice that `sched_yield()` in a no-op on some platforms (does nothing, just wasting CPU cycles), but Mutex wakeup can be slow, high contention makes them into an annoyance and x86 platforms support a `pause` assembly call, accessible using [`_mm_pause()`](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=pau&expand=3845) with `#include "emmintrin.h"` (hopefully your system maps `sched_yield()` to this... – Myst Jul 08 '16 at 02:58
  • 3
    @Myst: If the expectation is no contention, mutex will perform no worse than a spinlock in the expected case, but still pathologically worse in the unexpected case. See http://stackoverflow.com/questions/6603404/when-is-pthread-spin-lock-the-right-thing-to-use-over-e-g-a-pthread-mutex/6605443#6605443 – R.. GitHub STOP HELPING ICE Jul 08 '16 at 14:57
  • @R.. , Thanks for the link. I'm aware my comment was disorganized, the answer in the link was a better resource and I enjoyed reading it. – Myst Jul 08 '16 at 18:37

1 Answers1

4

If the same data will be modified concurrent with access from another thread, you only have two options: locking or using an atomic data type. There is no such thing as "using local variables to guard it". Of the two options you have, locking and atomics, the bulk of their runtime cost is memory (cache) synchronization with other cores and it should be roughly the same for either one of them. This is a nontrivial cost (on the order of tens of cycles most likely) but it's not one you can opt out of; there's no way to obtain correctness without it.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711