Is there a C++11 standards compliant (or if not compliant, at least generally acceptable) way to determine if an address is aligned with a cache line boundary?
E.g. something like this:
T* p = SOMETHING;
bool aligned = reinterpret_cast< std::uintptr_t > (p) % CACHE_LINE_SIZE == 0;
If you have a C++11-compliant compiler, then its documentation tells you.
As already mentioned by Igor in the comments, the rules for reinterpret_cast
include:
A pointer can be explicitly converted to any integral type large enough to hold it. The mapping function is implementation-defined.
That term doesn't just mean "non-portable", it adds specific requirements, found in 1.3.10:
implementation-defied behavior
behavior, for a well-formed program construct and correct data, that depends on the implementation and that each implementation documents
If your compiler does not document whether a pointer converted to integer is actually a memory address, then it is not a C++ compiler.
There's a std::align
function but it's apparently not much in demand: it's missing in gcc 4.9 and badly bugged in MSVC.
The proposed implementation of it (it's short enough to just read) is
inline void *align( std::size_t alignment, std::size_t size,
void *&ptr, std::size_t &space ) {
std::uintptr_t pn = reinterpret_cast< std::uintptr_t >( ptr );
std::uintptr_t aligned = ( pn + alignment - 1 ) & - alignment;
std::size_t padding = aligned - pn;
if ( space < size + padding ) return nullptr;
space -= padding;
return ptr = reinterpret_cast< void * >( aligned );
}
... a bit overkill here because to simply test for an already-aligned pointer it boils down to your method exactly (with bitbashing not %, but no matter). Its implementation is, as @IgorTandetnik points out, "unsurprising to those who know the addressing structure of the underlying machine"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With