对齐的类型和按值传递参数

时间:2010-12-12 23:32:33

标签: c++ stl alignment sse

按值传递对齐类型或结构与对齐类型不适用于某些实现。这会破坏STL容器,因为某些方法(例如resize)会按值获取它们的参数。

我使用Visual Studio 2008运行一些测试,并不完全确定何时以及如何通过值失败。我主要担心的是功能 foo 。它似乎工作正常,但它可能是内联或其他巧合的结果?如果我将其签名更改为 void foo(const __m128&)该怎么办?

非常感谢您的意见。谢谢。

struct A
{
    __m128 x;
    int n;
};

void foo(__m128);
void bar(A);

void f1()
{
    // won't compile
    // std::vector<A> vec1(3);

    // compiles, but fails at runtime when elements are accessed
    std::vector<__m128> vec2(3);

    // this seems to work. WHY???
    std::vector<__m128, some_16_byte_aligned_allocator<__m128> > vec3(3);

    __m128 x;
    A a;

    // passed by value, is it OK?
    foo(x);

    // won't compile
    //bar(a);
}

EDIT。即使使用对齐的分配器,STL也会失败,因为仍然存在按值传递问题。

找到此链接pass __m128 by value

2 个答案:

答案 0 :(得分:2)

我认为这样做的唯一安全方法是通过引用传递。有些平台(例如Xbox 360)支持在寄存器中传递向量参数,但我不认为这在x86上是可行的。

对于std::vector情况,您需要确保分配的内存对齐到16个字节;当你尝试对未对齐的向量执行大多数操作时,你会崩溃。

如果您支持多个平台,安全计划是使用typedef例如

typedef const MyVector& MyVectorParameter;

然后,您可以在支持矢量传值的平台上更改typedef。

答案 1 :(得分:1)

经常使用的resize()函数会导致所有对齐,也许你可以尝试专门为__m128设计矢量模板吗?