I just learnt about alignof
and alignas
C++ keywords but I can't think about any practical case where a developer would want to use these keywords.
Does somebody know any practical use case for these keywords?
I just learnt about alignof
and alignas
C++ keywords but I can't think about any practical case where a developer would want to use these keywords.
Does somebody know any practical use case for these keywords?
A common use case for the alignas
specifier is for the scenario where you want to pass multiple objects between different threads through a queue (e.g., an event or task queue) while avoiding false sharing. False sharing will result from having multiple threads competing for the same cache line when they are actually accessing different objects. It is usually undesirable due to performance degradation.
For example – assuming that the cache line size is 64 bytes – given the following Event
class:
struct Event {
int event_type_;
};
The alignment of Event
will correspond to the alignment of its data member, event_type_
. Assuming that the alignment of int
is 4 bytes (i.e., alignof(int)
evaluates to 4), then up to 16 Event
objects can fit into a single cache line. So, if you have a queue like:
std::queue<Event> eventQueue;
Where one thread pushes events into the back of the queue, and another thread pulls events from the front, we may have both threads competing for the same cache line. However, by properly using the alignas
specifier on Event
:
struct alignas(64) Event {
int event_type_;
};
This way, an Event
object will always be aligned on a cache line boundary so that a cache line will contain an Event
object at most. Therefore two or more threads will never be competing for the same cache line when accessing distinct Event
objects (if multiple threads are accessing the same Event
object, they will obviously compete for the same cache line).
Practical use cases from my experience:
Spare memory on pointers: if pointers to a type always end in zeros because of alignment of that type, then those always zero bits can be used to store something else. Example:
class Small { Aligned * ptr; bool b; }; // suppose having many instances
would take at least 8+1 bytes on 64bit architectures, but it can be compressed to 8 bytes by carefully union-ing the ptr and the bool. Before using the ptr you have to bitmask it, but that is a very fast instruction. Its a trade-off between memory and cpu.
memcpy
ing into them. This cannot be allowed to modify the value of any other object, including b
. But if these were sharing memory, it would. Padding bytes are part of an object's representation and thus cannot arbitrarily be used by some other object (unless that object is zero-sized). –
Physoclistous © 2022 - 2024 — McMap. All rights reserved.