0

I am looking for a way in C++ bool type (or possibly C int), that checking (if statement) and editing the bool in a single instruction. Google search got me nowhere, maybe I am using wrong keywords.

Example:

bool valid;
.
.
.
if(valid){
    valid = false;
    // do stuff
}

For now, I use std::atomic<bool>, but still, if(valid) and valid = false are different instructions, and in a multi thread environment, there are things getting in between. Is there a way to make this 2 operations atomic, without using mutexes ?

I am using GCC 11 / G++ 11.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
Max Paython
  • 1,595
  • 2
  • 13
  • 25
  • 3
    [std::atomic_compare_exchange()](https://en.cppreference.com/w/cpp/atomic/atomic_compare_exchange)? – Scheff's Cat Jan 13 '22 at 06:59
  • 2
    If you're programming in C++ then you're programming in C++ and only C++. Please don't tag (or mention) other unrelated languages. – Some programmer dude Jan 13 '22 at 07:00
  • @Someprogrammerdude Thanks for your input. There could be a way to do this with C integers (bit operators etc.). I mentioned this in the question. – Max Paython Jan 13 '22 at 07:01
  • 4
    `int`s and `bool`s are not atomic (in both C and C++), and attempting to access them from several threads would cause UB, no matter how clever the bit operations are. – HolyBlackCat Jan 13 '22 at 07:03
  • @Scheff'sCat I am using this code above, in a really frequently visited bottleneck part. Is that code introduce any expense in the manner of CPU cycles ? It is not clear in the docs. – Max Paython Jan 13 '22 at 07:03
  • @HolyBlackCat What about `std::atomic` and `std::atomic` ? – Max Paython Jan 13 '22 at 07:05
  • Those are ok... – HolyBlackCat Jan 13 '22 at 07:06
  • 1
    A synchronized communication between threads comes always to a certain performance price. You have to pay it by any chance or would introduce a data race. AFAIK, atomics are the cheapest kind of thread sync. If you are not using multiple threads (or valid is used (read/written) in one thread only), then just leave it as is... (and forget about atomics). – Scheff's Cat Jan 13 '22 at 07:06
  • @Scheff'sCat Unfortunately, I have more than 10 threads, accessing that variable many many times :) So any clever way of atomizing (is this a word ?), I would welcome with open arms. – Max Paython Jan 13 '22 at 07:08
  • FYI: [SO: Multithreading program stuck in optimized mode but runs normally in -O0](https://stackoverflow.com/a/58516119/7478597) ;-) – Scheff's Cat Jan 13 '22 at 07:11
  • @Scheff'sCat It seems there is a type `std::atomic_flag`. It seems a bit lighter than `std::atomic`. Unfortunately it doesn't have method like `test_and_clear`. But it does have `test_and_set`. Maybe if I switch the logic of my `if` statement, I could use this. – Max Paython Jan 13 '22 at 07:19
  • If in doubt have a look onto the assembly code e.g. in [Compiler Explorer](https://godbolt.org/). Sometimes, it's surprising how different C++ code is compiled into to the exact same binary code... – Scheff's Cat Jan 13 '22 at 07:23
  • If your program might run on different CPU types in the future (e.g. x86, ARM and Sparc), you either have to use a very tricky programming or consider some performance loss because there are CPUs that do not support atomic access to variables at all. – Martin Rosenau Jan 13 '22 at 07:30
  • 1
    who sets the flag? The best synchronization between many threads is no synchronization or as little as possible, so you need to consider the whole picture. Maybe a condition variable would help – 463035818_is_not_an_ai Jan 13 '22 at 07:50
  • @463035818_is_not_a_number This code behaves like an entry invalidator for this concurrent DB I wrote. synchronization is necessary, the implementation details are up for debate however. – Max Paython Jan 13 '22 at 07:58
  • 2
    This doesn't have a whole lot to do with the higher level language but everything to do with what the underlying CPU is capable of. You can't do it in a single instruction if there is no "check and modify" instruction available, obviously. There exists no C++ library which can re-design the CPU ISA. – Lundin Jan 13 '22 at 08:32

0 Answers0