x86-64 上检查指针范围是不是跨越 N 字节对齐地址的最快方法?
Posted
技术标签:
【中文标题】x86-64 上检查指针范围是不是跨越 N 字节对齐地址的最快方法?【英文标题】:Fastest method on x86-64 to check if pointer range straddles an N byte aligned address?x86-64 上检查指针范围是否跨越 N 字节对齐地址的最快方法? 【发布时间】:2012-09-04 22:03:26 【问题描述】:给定一个指向 T 的指针,我想确定 T 是否跨越 N 字节对齐的地址。在实践中,我真的只关心 0-5 字节大小的对象是跨越 8 字节还是 16 字节边界,但我写了这个通用版本:
template<class T, unsigned long N>
bool straddlesBoundary(T* obj)
unsigned long before = (unsigned long)obj & ~(N-1);
unsigned long after = ((unsigned long)obj + sizeof(T) - 1) & ~(N-1);
return before != after;
基本上,将地址向下舍入到最近的 N 字节对齐地址,然后将指针增量 T 减去 1 的大小(因为在下一个边界右结束的 T 不算作跨接)并向下舍入到最近的 N 字节对齐地址,如果它们匹配,你就知道它不会跨越。
有没有更快的方法来做到这一点?这是我自己编的,不知道有没有标准检查。
编辑:注意,我假设 T 小于 N。
【问题讨论】:
好吧,#define ~(N-1) BA
并相应地替换会有所帮助。
你为什么在乎?您是否测量过程序的性能并发现这是一个瓶颈?
@MikeSeymour N 在编译时是已知的,所以这样做不会为您节省一些计算吗?或者任何编译器都会自动优化它?
@MattPhillips:对不起,“什么?”,我的意思是“你是什么意思?”。 ~(N-1)
不是有效的宏名称,即使是,用未定义的名称替换它只会使编译失败。如果您的意思是将出现的~(N-1)
替换为BA
,然后添加#define BA ~(N-1)
以使预处理器撤消更改,那么您将在预处理后得到相同的代码。无论如何,~(N-1)
与N
一样是编译时常量,因此无需尝试优化该计算。
@MikeSeymour Doh!!大声笑是的,那只是一个错字。不要经常使用#defines。我的意思是在编译时将~(N-1)
替换为BA
。您的其他意见已得到适当记录。
【参考方案1】:
你可以这样做:
unsigned long offset = (unsigned long)obj & (N-1);
return offset > N - sizeof(T);
(与您一样,此代码仅在 N 是 2 的幂时才有效。)
【讨论】:
哦,呵呵。这绝对更好:) 我会等一会儿检查是否接受,看看是否有其他答案进来...... @JosephGarvin:如果您可以使用std::uintptr_t
from <cstdint>
,您应该使用它。
现在我再看一遍,我认为它不正确。 'offset' 将是一个大指针地址,只有一些底部位清零。我想你的意思是“offset = obj - ((unsigned long)obj & ~(N-1))”?那还是去掉“~”?
@AntoineMathys: true,但前提是 N 是编译时常量。以上是关于x86-64 上检查指针范围是不是跨越 N 字节对齐地址的最快方法?的主要内容,如果未能解决你的问题,请参考以下文章
在 x86-64 上,32 位应用程序是不是比 64 位应用程序有性能优势?