Reputation: 429
I know atomic variable is lock-free!!
It doesn't lock thread, but I have one question..
Read-Modify-Store operation like std::atomic::fetch_add is also executed atomically???
I think this operation isn't just a one instruction.
It need multiple cycle... So If i doesn't lock memory bus ( Actually i don't know if mutex locking contain memory bus lock), Other thread can make memory operation between Read and Store.
So I think it require locking even if atomic variable...
Am i knowing well???
Upvotes: 0
Views: 241
Reputation: 109
You konwing is right in in earlyer x86 architecture.
In the x86 architecture, the instruction prefix LOCK is provided.Atomic variables depend on this directive.Early a LOCK is implemented by locking a bus to prevent memory access from other CPU cores. As you can imagine, this implementation is very inefficient
Most x86 processors support the hardware implementation of CAS, which ensures the correctness of atomic operation in multi-processor and multi-core systems. The implementation of CAS also does not lock the bus and only blocks access by other CPUs to the cache blocks that check the associated memory. let show you code. example code is :
#include <iostream>
#include <thread>
#include <atomic>
std::atomic<long long> data;
void do_work()
{
data.fetch_add(1, std::memory_order_relaxed);
}
int main()
{
std::thread th1(do_work);
std::thread th2(do_work);
std::thread th3(do_work);
std::thread th4(do_work);
std::thread th5(do_work);
th1.join();
th2.join();
th3.join();
th4.join();
th5.join();
std::cout << "Result:" << data << '\n';
}
Convert the above code into instructions. In gcc 8 do_work function translated into
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], 1
mov DWORD PTR [rbp-12], 0
mov rax, QWORD PTR [rbp-8]
mov edx, OFFSET FLAT:data
lock xadd QWORD PTR [rdx], rax
nop
pop rbp
ret
use lock xadd
to ensure atomic operator.
Upvotes: 1