Let's say I have an allocator which gives out entire cachelines per request. So each allocation will begin on a new cacheline.
constexpr auto L1 = std::hardware_destructive_interference_size;
std::byte* allocator_cachelines = static_cast<std::byte*>(
::operator new(TOTAL_CACHELINES*L1, std::align_val_t{L1}));
// ALL TYPES USING THE ALLOCATOR HAVE IMPLICIT LIFETIME
// (are trivially copyable and destructable)
struct ABC { int i=0; };
struct XYZ { float f=1.f; };
auto* abc = reinterpret_cast<ABC*>(allocator.allocate(ABC_COUNT * sizeof(ABC)));
// allocate returns enough cachelines from allocator_cachelines
// to fulfill the request,
// plus the bookkeeping to mark those cachelines as in use
std::cout << abc[0].i; // OK?
// since ABC is the first type stored within the memory,
// does it's implicit lifetime begin?
Now what happens if that memory is deallocated and reused for another implicit lifetime type.
allocator.deallocate(abc);
// deallocate marks the returned abc cachelines as free for reuse
auto* xyz = reinterpret_cast<XYZ*>(allocator.allocate(XYZ_COUNT * sizeof(XYZ)));
// allocate returns the abc cachelines which were just freed
std::cout << xyz[0].f; // OK?
// or do I need to first do
xyz[0] = XYZ{};
std::cout << xyz[0].f; // OK NOW?
Also if access to the allocator is controlled by an std::mutex. Would this solve any strict aliasing violations? Since a mutex introduces memory fences, memory reordering can't cause violations of strict aliasing since the allocating and deallocating gives mutual exclusive types to the reused memory (assuming that pointers to the previous data type are not cached for later use).
Lastly if I have an array of floats allocated from the allocator and use it with SIMD instrinsics.
Would I have to write to all elements to avoid strict aliasing violations?
Since the SIMD instrinsic could access elements at the end of the array which were never written to.
For example
float array : [0, 1, 2, 3]
If 0, 1, 2 were written to and 3 wasn't (and a another type had occupied those bytes previously).
Any SIMD instrinsic load of the 4 floats would access 3 as a different type then what was last written to it.