【问题标题】:Memory alignment check内存对齐检查
【发布时间】:2011-09-08 13:54:51
【问题描述】:

我想检查分配的内存是否对齐。我正在使用_aligned_malloc(size, align); 它返回一个指针。例如,我可以通过简单地将指针内容除以 16 来检查它吗?如果指针内容能被 16 整除,是否意味着内存按 16 字节对齐?

【问题讨论】:

  • 您是否有不信任_aligned_malloc()函数的原因?
  • 我正在尝试调试程序。我不知道问题出在哪里,但我肯定知道这是内存对齐问题。例如,我可以通过将指针除以 16 来检查它吗?
  • “我肯定知道这是内存对齐问题” 您可能需要指出您是如何知道的!听起来你在谈论 Windows。你具体分配了什么?您遇到的问题的详细信息是什么?
  • 我正在尝试将 linux 程序移植到 windows。如果我禁用 SSE 指令,它运行没有任何问题。

标签: c visual-studio


【解决方案1】:

根据定义,“对齐”指针意味着指针的数值可以被 N 整除(其中 N 是所需的对齐方式)。要检查这一点,请将指针转换为合适大小的整数,取模数 N,并检查结果是否为零。在代码中:

bool is_aligned(void *p, int N)
{
    return (int)p % N == 0;
}

如果要手动检查指针值,只需查看指针的十六进制表示,看看它是否以所需的 0 位数结尾。例如,一个 16 字节对齐的指针值将始终以四个零位结束。

【讨论】:

  • 由于指针对齐问题总是涉及到 2 的幂,因此在单位宽度位之后取与位会更快:return ((uintptr_t)p & (uintptr_t)(N - 1)) == 0(这用最多一个减法和一个按位与。)此外,在 C 中,这些天将指针转换为无符号整数(有符号可能有意想不到的副作用)应该是 C99 uintptr_t(使用 stdint.h)而不是 int;跨度>
  • return ((uintptr_t)p & (uintptr_t)(sizeof(p) - 1)) == 0 这样的东西是否适用于任何指针?假设指针始终与其底层类型对齐。
  • @JodyLeeBruchon 毫无疑问,编译器优化了这一点。
  • @Antonio 仅当 N 是编译时已知的常数并且是 2 的幂。否则,AND 确实会更快。
【解决方案2】:

在现代 Unix 系统上,malloc 返回的指针很可能是 16 字节对齐的,因为这对于 SSE 之类的东西是必需的。要检查 2 的幂的对齐情况,您可以使用:

((unsigned long)p & (ALIGN - 1)) == 0

这只是(p % ALIGN) == 0 的更快版本。 (如果ALIGN 是一个常量,您的编译器可能会自动使用上述更快的版本。)

【讨论】:

  • 实际上,如果您使用带符号的类型(如long),编译器无法在不添加一些额外补丁代码的情况下将% 优化为&。你应该使用unsigned long
【解决方案3】:

malloc 返回的内存为所有内容对齐(即,它通常使用适用于所有内容的对齐方式)*。这意味着,如果您有对齐问题,那就是另外一回事了。

http://www.delorie.com/gnu/docs/glibc/libc_31.html

http://msdn.microsoft.com/en-us/library/ms859665.aspx

(高阶对齐似乎有例外,无论如何这是一个不寻常的要求。)

【讨论】:

  • 根据specification,malloc 仅保证“分配成功时返回的指针应适当对齐,以便可以将其分配给指向任何类型对象的指针,然后用于访问此类分配空间中的一个对象”。这是特定于架构的。例如,在 x86 中是 8 个字节,在 x86-64 中是 16 个字节。我们应该犹豫说“一种适用于所有事物的对齐方式”,因为肯定有反例。
猜你喜欢
  • 1970-01-01
  • 2020-01-17
  • 1970-01-01
  • 1970-01-01
  • 2015-09-24
  • 2012-09-28
  • 2021-12-15
  • 2013-10-11
  • 2010-11-07
相关资源
最近更新 更多