小缓冲区优化和对齐

时间:2012-10-25 20:53:04

标签: c++ c++11

我正在编写遗留API的 C ++ 包装器。这个API为我提供了一个指针值来保存额外的数据,我想用它实现小缓冲区优化

我已经实现了is_small_pod 元函数,用于检查给定类型是否为 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 );
}

我是否正确实施此优化?我相信当值对齐与指针的对齐不兼容时,这将失败(奇数角情况可能如此)。这种情况是否可能,或者我只是过度思考它?我应该如何扩展元函数以检查兼容的对齐

2 个答案:

答案 0 :(得分:8)

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

  

3.11对齐[basic.align]

     

[...] alignment 是一个实现定义的整数值,表示可以分配给定对象的连续地址之间的字节数。

     

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* )
    >
{};

答案 1 :(得分:0)

就像一般方法一样,你总是可以尝试测试你的理论。我想你会做这样的事情:

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*大小的对齐方式。这只是一个想法。 =)