Reputation: 597
memcpy(a, b, sizeof(a));
v.s.
a[0] = b[0];
a[1] = b[1];
...
Suppose that memcpy
should have smaller code size and high efficiency, but is there any risk to memcpy
in multi-thread system?
Upvotes: 3
Views: 4039
Reputation: 3126
Both code is the same to the compiler, and even compiles exactly to the same assembly code at optimization level clang -O1
, gcc -O2
or higher.
Modern C doesn’t enforce “sequentially consistent ordering”, which allows certain reordering to happen:
a[0] = b[0];
and a[1] = b[1];
if the compiler knows abs(a - b) ≥ sizeof a / sizeof a[0]
.If you want to prevent 1 from happening, you need to insert a compiler fence (e.g., asm("" ::: "memory");
.
Similarly, if you want to prevent 2 and 3 from happening, you need to insert a memory fence (e.g., atomic_thread_fence
) or use a mutex which produces an appropriate memory fence whenever you lock or unlock it.
Observing the side-effects of any non-atomic operation from another thread without an appropriate synchronization mechanism is undefined behavior.
Based on the above assumptions, the compiler can freely make these two transformations:
a[0] = b[0]; …
sequence into a memcpy
, if the compiler knows a
and b
doesn’t overlap.a[0] = b[0]; …
sequence into a memmove
, if the compiler knows a ≤ b
.a[0] = b[0]; …
sequence into some SIMD instructions so both statements are executed in parallel, if the compiler knows a
and b
doesn’t overlap within the distance of a SIMD vector length.sizeof a
is small.Therefore, to the compiler, there is no difference. No matter whether your program is single-threaded or multi-threaded.
Upvotes: 0
Reputation: 320541
If the buffers are exclusive, meaning that threads are not competing for access to the data involved in the copying, then memcpy
is perfectly safe to use in multi-threaded environment. The function has no persistent state and no other side-effects besides modifying the target buffer.
Also, you can safely perform muti-threaded copying from a buffer shared by any number of threads, as long as no thread attempts to change that buffer.
But once there's a competition between the threads for writing into any shared buffers, memcpy
no longer guarantees thread safety, i.e. the operation is not atomic. Aside from what is described in 2, two simultaneous memcpy
s operating on the same buffer will interfere with each other and produce unpredictable results.
Upvotes: 7
Reputation: 502
If you do not use lock to ensure exclusive, using memcpy()
only will be very dangerous! The memcpy()
is only responsible for copying memory, don't ensure thread safe, you should add lock by yourself. In C language, in user's space, you can use mutex
for ensuring exclusive.
Upvotes: 1