gpt4 book ai didi

c - 如何判断内存是否对齐?

转载 作者:IT王子 更新时间:2023-10-28 23:28:39 26 4
gpt4 key购买 nike

我是使用 SSE/SSE2 指令优化代码的新手,直到现在我还没有走得太远。据我所知,一个常见的 SSE 优化函数如下所示:

void sse_func(const float* const ptr, int len){
if( ptr is aligned )
{
for( ... ){
// unroll loop by 4 or 2 elements
}
for( ....){
// handle the rest
// (non-optimized code)
}
} else {
for( ....){
// regular C code to handle non-aligned memory
}
}
}

但是,我如何正确确定 ptr 指向的内存是否通过例如对齐16 字节?我认为我必须包含非对齐内存的常规 C 代码路径,因为我无法确保传递给此函数的每个内存都将对齐。并且使用内部函数将数据从未对齐的内存加载到 SSE 寄存器似乎非常慢(甚至比常规 C 代码慢)。

提前谢谢你...

最佳答案

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

强制转换为 void *(或等价的 char *)是必要的,因为标准只保证对 uintptr_t 的可逆转换void *.

如果您想要类型安全,请考虑使用内联函数:

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

如果 byte_count 是编译时常量,则希望编译器优化。

为什么我们需要转换成 void *

C 语言允许对不同的指针类型进行不同的表示,例如你可以有一个 64 位的 void * 类型(整个地址空间)和一个 32 位的 foo * 类型(一段)。

foo * -> void * 的转换可能涉及实际计算,例如添加偏移量。该标准还让实现将(任意)指针转换为整数时会发生什么,但我怀疑它通常被实现为 noop。

对于这样的实现,foo * -> uintptr_t -> foo * 可以工作,但是 foo * -> uintptr_t -> void *void * -> uintptr_t -> foo * 不会。对齐计算也不会可靠地工作,因为您只检查相对于段偏移的对齐,这可能是也可能不是您想要的。

结论:始终使用 void * 来获得独立于实现的行为。

关于c - 如何判断内存是否对齐?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1898153/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com