Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If `atomic<T>` is lock free and has the same size as `T`, will the memory layout be the same?

This question here indicates that std::atomic<T> is generally supposed to have the same size as T, and indeed that seems to be the case for gcc, clang, and msvc on x86, x64, and ARM.

In an implementation where std::atomic<T> is always lock free for some type T, is it's memory layout guaranteed to be the same as the memory layout of T? Are there any additional special requirements imposed by std::atomic, such as alignment?

like image 898
Alecto Irene Perez Avatar asked Jan 01 '23 00:01

Alecto Irene Perez


2 Answers

Upon reviewing [atomics.types.generic], which the answer you linked quotes in part, the only remark regarding alignment is the note which you saw before:

Note: The representation of an atomic specialization need not have the same size as its corresponding argument type. Specializations should have the same size whenever possible, as this reduces the effort required to port existing code

In a newer version:

The representation of an atomic specialization need not have the same size and alignment requirement as its corresponding argument type.

Moreover, at least one architecture, IA64, gives a requirement for atomic behavior of instructions such as cmpxchg.acq, which indicates that it's likely that a compiler targeting IA64 may need to align atomic types differently than non-atomic types, even in the absence of a lock.

Furthermore, the use of a compiler feature such as packed structs will cause alignment to differ between atomic and non-atomic variants. Consider the following example:

#include <atomic>
#include <iostream>
struct __attribute__ ((packed)) atom{
    char a;
    std::atomic_long b;
};
struct __attribute__ ((packed)) nonatom{
    char a;
    long b;
};

atom atom1;
nonatom nonatom1;
int disp_aligns(int num) {
    std::cout<< alignof(atom1.b) << std::endl;
    std::cout<< alignof(nonatom1.b) << std::endl;
}

On at least one configuration, the alignment of atom1.b will be on an 8-byte boundary, while the alignment of nonatom1.b will be on a 1-byte boundary. However, this is under the supposition that we requested that the structs be packed; it's not clear whether you are interested in this case.

like image 145
nanofarad Avatar answered Jan 13 '23 16:01

nanofarad


From the standard:

The representation of an atomic specialization need not have the same size and alignment requirement as its corresponding argument type.

So the answer, at least for now, is no, it is not guaranteed to be the same size, nor have same alignment. But it might have, unless it doesn't and then it won't.

like image 29
wally Avatar answered Jan 13 '23 15:01

wally