【问题标题】:Aligned types and passing arguments by value对齐类型和按值传递参数
【发布时间】:2011-05-24 09:49:47
【问题描述】:

通过值传递对齐类型或具有对齐类型的结构不适用于某些实现。这会破坏 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);
}

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

找到这个链接pass __m128 by value

【问题讨论】:

  • 您收到的编译错误/警告是什么?我假设类似“形式参数......不会对齐”?
  • 这就是我得到的。错误 C2719:“未命名参数”:带有 __declspec(align('16')) 的形式参数不会对齐
  • 在 x64 中,函数参数支持 16 字节对齐,所以这个问题就消失了。我知道这并不能解决您当前的问题,但是,嘿,总比没有好。 ;)
  • 事实证明,按值传递__m128是可以的。按照网络链接。
  • 哪种类型的编译器“支持”它实际上无法满足对齐要求的类型?

标签: c++ stl alignment sse


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

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

    typedef const MyVector& MyVectorParameter;
    

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

    【讨论】:

    • 用 std::vector<__m128> 替换分配器帮助,但 std::vector 仍然无法编译。
    • 你检查sizeof(A)了吗?如果不是 16 字节的倍数,那么向量分配的数组存储的后续元素将不会对齐,即使存储的开头对齐。
    • 在我的平台上,A 的大小是 32 字节。错误的对齐会导致运行时崩溃,但无论分配器如何,vector都不会编译。
    猜你喜欢
    • 1970-01-01
    • 2012-11-16
    • 2017-01-17
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2012-12-18
    • 2012-05-22
    • 1970-01-01
    相关资源
    最近更新 更多