C++ x86-64上检查指针范围是否跨越N字节对齐地址的最快方法?

C++ x86-64上检查指针范围是否跨越N字节对齐地址的最快方法?,c++,alignment,bit-manipulation,x86-64,simd,C++,Alignment,Bit Manipulation,X86 64,Simd,给定一个指向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 l

给定一个指向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;
}
模板
布尔跨界边界(T*obj)
{
前无符号长=(无符号长)obj&~(N-1);
无符号长after=((无符号长)obj+sizeof(T)-1)&~(N-1);
返回之前!=之后;
}
基本上,将地址向下四舍五入到最近的N字节对齐地址,然后将指针增量取T减1的大小(因为在下一个边界右端的T不算跨接),然后向下四舍五入到最近的N字节对齐地址,如果它们匹配,您知道它不跨接

有没有更快的方法?这是我编的,我不知道有没有标准支票

编辑:注意,我假设T小于N。您可以:

unsigned long offset = (unsigned long)obj & (N-1);
return offset > N - sizeof(T);
(此代码与您的代码一样,仅当N是2的幂时有效。)

您可以执行以下操作:

unsigned long offset = (unsigned long)obj & (N-1);
return offset > N - sizeof(T);

(这个代码和你的一样,只有当N是2的幂时才起作用。)

好吧,
#定义~(N-1)BA
并相应地进行替换会有一点帮助。你为什么在意呢?你测量过你的程序的性能并发现这是一个瓶颈吗?@MikeSeymour N在编译时就知道了,所以这样做会不会节省一些计算?或者任何编译器会自动优化它吗?@MattPhillips:对不起,我说的“什么?”是指“你是什么意思?”<代码>~(N-1)不是有效的宏名称,即使是,用未定义的名称替换它也会导致编译失败。如果您的意思是将出现的
~(N-1)
替换为
BA
,然后添加
#define BA~(N-1)
以使预处理器撤消更改,那么预处理后您将得到相同的代码。在任何情况下,
~(N-1)
N
一样是一个编译时常量,因此无需尝试优化该计算。@MikeSeymour Doh!!哈哈,是的,那只是个打字错误。不要经常使用这个。我的意思是简单地在编译时将
~(N-1)
替换为
BA
。你的其他观察结果也得到了适当的注意。好吧,
#定义~(N-1)BA
,并相应地进行替换会有所帮助。你为什么在意呢?你测量过你的程序的性能并发现这是一个瓶颈吗?@MikeSeymour N在编译时就知道了,所以这样做会不会节省一些计算?或者任何编译器会自动优化它吗?@MattPhillips:对不起,我说的“什么?”是指“你是什么意思?”<代码>~(N-1)不是有效的宏名称,即使是,用未定义的名称替换它也会导致编译失败。如果您的意思是将出现的
~(N-1)
替换为
BA
,然后添加
#define BA~(N-1)
以使预处理器撤消更改,那么预处理后您将得到相同的代码。在任何情况下,
~(N-1)
N
一样是一个编译时常量,因此无需尝试优化该计算。@MikeSeymour Doh!!哈哈,是的,那只是个打字错误。不要经常使用这个。我的意思是简单地在编译时将
~(N-1)
替换为
BA
。你的其他观察结果也被注意到了。这绝对是更好的:)我会等一等,看看是否还有其他答案……约瑟夫加文:你应该使用
中的
std::uintpttr\t
,如果你可以的话。现在我再看一遍,我认为这是不对的“偏移量”将是一个大的指针地址,只有一些底部位被调零。我想你的意思是“offset=obj-((无符号长)obj&~(N-1))”?或者删除“~”?@AntoineMathys:true,但前提是N是编译时常数。噢,duh。这绝对是更好的:)我会等一等,看看是否还有其他答案……约瑟夫加文:你应该使用
中的
std::uintpttr\t
,如果你可以的话。现在我再看一遍,我认为这是不对的“偏移量”将是一个大的指针地址,只有一些底部位被调零。我想你的意思是“offset=obj-((无符号长)obj&~(N-1))”?或者删除“~”?@AntoineMathys:true,但仅当N是编译时常量时。