如何确定 C99 中所需的最大对齐
How to determine maximum required alignment in C99
是否有一种仅依赖于 C99 标准提供的可移植方法来找出任何数据类型所需的最大对齐要求。
类似于 C++11 中的 maxalign_t
。
我目前正在做的是计算 int
、long int
、long long int
、[=15= 对齐的最小公倍数 (lcm
) ]、void *
和 size_t
作为确定对齐的最大努力方式。
更新:
我目前需要这个来实现围绕 malloc
的包装器,它在内存块的开头存储元数据,returns 一个地址比 malloc
返回的地址更高的指针。
确实没有一个好的方法来做到这一点,这就是 maxalign_t
由 C11 引入的原因。虽然,我无法想象一个普通系统存在比 intmax_t
更高对齐要求的类型,因此您不妨使用它并在 maxalign_t
不可用时为 99% 的系统获得正确答案。
您可以通过分配几个块并查看每个块是否在 16、8 或 4 字节边界上对齐来凭经验确定支持的最大对齐。
bool GetConsistentAlignment( std::size_t alignment )
{
const unsigned int chunkCount = 16;
void * places[ chunkCount ];
memset( places, 0, sizeof(places) );
bool consistent = true;
for ( unsigned int ii = 0; ii < chunkCount; ++ii )
{
const std::size_t size = 1024 + rand() % 4096;
void * chunk = malloc( size );
places[ ii ] = chunk;
}
for ( unsigned int ii = 0; ii < chunkCount; ++ii )
{
void * chunk = places[ ii ];
const std::size_t place = reinterpret_cast< const std::size_t >( chunk );
if ( place % alignment != 0 )
{
consistent = false;
}
free( chunk );
}
return consistent;
}
std::size_t GetMaxSupportedAlignment()
{
static std::size_t maxAlignment = 0;
if ( maxAlignment == 0 )
{
std::srand( std::time( 0 ) );
std::size_t alignment = 64;
while ( alignment > 1 )
{
const bool isConsistentAlignment = GetConsistentAlignment( alignment );
if ( isConsistentAlignment )
{
break;
}
alignment /= 2;
}
maxAlignment = alignment;
}
return maxAlignment;
}
调用 GetMaxSupportedAlignment()
将 return 在 64 位操作系统上为 8 个,在许多 32 位系统上为 4 个。
是否有一种仅依赖于 C99 标准提供的可移植方法来找出任何数据类型所需的最大对齐要求。
类似于 C++11 中的 maxalign_t
。
我目前正在做的是计算 int
、long int
、long long int
、[=15= 对齐的最小公倍数 (lcm
) ]、void *
和 size_t
作为确定对齐的最大努力方式。
更新:
我目前需要这个来实现围绕 malloc
的包装器,它在内存块的开头存储元数据,returns 一个地址比 malloc
返回的地址更高的指针。
确实没有一个好的方法来做到这一点,这就是 maxalign_t
由 C11 引入的原因。虽然,我无法想象一个普通系统存在比 intmax_t
更高对齐要求的类型,因此您不妨使用它并在 maxalign_t
不可用时为 99% 的系统获得正确答案。
您可以通过分配几个块并查看每个块是否在 16、8 或 4 字节边界上对齐来凭经验确定支持的最大对齐。
bool GetConsistentAlignment( std::size_t alignment )
{
const unsigned int chunkCount = 16;
void * places[ chunkCount ];
memset( places, 0, sizeof(places) );
bool consistent = true;
for ( unsigned int ii = 0; ii < chunkCount; ++ii )
{
const std::size_t size = 1024 + rand() % 4096;
void * chunk = malloc( size );
places[ ii ] = chunk;
}
for ( unsigned int ii = 0; ii < chunkCount; ++ii )
{
void * chunk = places[ ii ];
const std::size_t place = reinterpret_cast< const std::size_t >( chunk );
if ( place % alignment != 0 )
{
consistent = false;
}
free( chunk );
}
return consistent;
}
std::size_t GetMaxSupportedAlignment()
{
static std::size_t maxAlignment = 0;
if ( maxAlignment == 0 )
{
std::srand( std::time( 0 ) );
std::size_t alignment = 64;
while ( alignment > 1 )
{
const bool isConsistentAlignment = GetConsistentAlignment( alignment );
if ( isConsistentAlignment )
{
break;
}
alignment /= 2;
}
maxAlignment = alignment;
}
return maxAlignment;
}
调用 GetMaxSupportedAlignment()
将 return 在 64 位操作系统上为 8 个,在许多 32 位系统上为 4 个。