How to determine if memory is aligned?

后端 未结 8 2341
生来不讨喜
生来不讨喜 2020-11-29 18:27

I am new to optimizing code with SSE/SSE2 instructions and until now I have not gotten very far. To my knowledge a common SSE-optimized function would look like this:

<
8条回答
  •  悲&欢浪女
    2020-11-29 18:55

    #define is_aligned(POINTER, BYTE_COUNT) \
        (((uintptr_t)(const void *)(POINTER)) % (BYTE_COUNT) == 0)
    

    The cast to void * (or, equivalenty, char *) is necessary because the standard only guarantees an invertible conversion to uintptr_t for void *.

    If you want type safety, consider using an inline function:

    static inline _Bool is_aligned(const void *restrict pointer, size_t byte_count)
    { return (uintptr_t)pointer % byte_count == 0; }
    

    and hope for compiler optimizations if byte_count is a compile-time constant.

    Why do we need to convert to void * ?

    The C language allows different representations for different pointer types, eg you could have a 64-bit void * type (the whole address space) and a 32-bit foo * type (a segment).

    The conversion foo * -> void * might involve an actual computation, eg adding an offset. The standard also leaves it up to the implementation what happens when converting (arbitrary) pointers to integers, but I suspect that it is often implemented as a noop.

    For such an implementation, foo * -> uintptr_t -> foo * would work, but foo * -> uintptr_t -> void * and void * -> uintptr_t -> foo * wouldn't. The alignment computation would also not work reliably because you only check alignment relative to the segment offset, which might or might not be what you want.

    In conclusion: Always use void * to get implementation-independant behaviour.

提交回复
热议问题