小型缓冲液优化和对齐

Small Buffer Optimization and alignment

本文关键字:对齐 优化 缓冲 小型      更新时间:2023-10-16

我在遗留API上编写A C 包装器。此API为我提供了保留额外数据的指针值,我想用它来实现小型缓冲区优化

我已经实现了is_small_pod metafunction 检查给定类型是否为 pod ,并且适合void*

template< typename Type >
struct is_small_pod
  : std::integral_constant<
        bool
      , std::is_pod< Type >::type::value
        && sizeof( Type ) <= sizeof( void* )
    >
{};

我要设置这样的值:

// void*& param;
if( detail::is_small_pod< Type >() )
{
    *static_cast< Type* >( &param ) = value;
} else {
    param = new Type( value );
}

我是否正确实施了此优化?我相信,当价值对齐与指针的对齐不兼容时(奇数角案例)。这种情况甚至可能,还是我只是想过它?我应该如何扩展 metafunction 还可以检查兼容对齐

类型的对齐不可能大于该类型的大小。

3.11对齐[basic.align]

[...] AN ANIGNMENT 是一个实现限制的整数值,代表可以分配给定对象的连续地址之间的字节数。

5.3.3 sizeof [expr.sizeof]

2 - [...] n 元素的数组的大小是 n 乘以元素的大小。

因此,只有在alignof(void *) < sizeof(void *)时,您的代码只能在大多数平台上破裂。

为了安全,您可以写:

template< typename Type >
struct is_small_pod
  : std::integral_constant<
        bool
      , std::is_pod< Type >::type::value
        && sizeof( Type ) <= sizeof( void* )
        && alignof( Type ) <= alignof( void* )
    >
{};

作为一种一般方法,您可以随时尝试测试理论。我想你会做这样的事情:

template< class Type >
bool TestAlignmentSanity( Type value )
{
    // This function is only valid for small POD types
    if( !detail::is_small_pod< Type >() )
        return false;
    // Temporary space covering alignments spanning the size of a void*
    const int nBytes = sizeof(void*);
    char buffer[sizeof(Type) + nBytes - 1];
    // For each target alignment, test that a copy is successful.
    for( int i = 0; i < nBytes; i++ )
    {
       Type * target = static_cast< Type* >( &buffer[i] );
       // Sanity-check that the pointer was actually aligned as we requested
       if( (char*)target != &buffer[i] ) return false;
       // Copy and test that the result is as expected.  Assumes '==' operator
       // is defined...  Otherwise, implement with byte comparisons.
       *target = value;
       if( !(*target == value) ) return false;
    }
    return true;
}

在这里,我测试了数据类型可以复制为任何跨越void*大小的对齐。这只是一个想法。=)