【发布时间】:2014-05-10 01:27:42
【问题描述】:
在 Visual Studio 2013 中,存在一个新的调用约定 _vectorcall。它适用于可在 SSE 寄存器中传递的 SSE 数据类型。
您可以像这样指定成员函数的调用约定。
struct Vector{//a 16 byte aligned type
_m128i _vectorcall operator *(Vector a);
};
这可行,它可以编译,尽管有 16 个对齐要求,但类型可以按值传递。
另一方面,如果我尝试将它附加到任何构造函数(这似乎完全合乎逻辑),它会失败。
struct Vector
_vectorcall Vector(SomeOtherTypeWith16Alignment a);
};
编译器吐出警告信息(我有警告为错误):
警告 C4166:构造函数/析构函数的非法调用约定。
强迫我把代码改成这样:
struct Vector{
Vector(SomeOtherTypeWith16Alignment a); //fails to compile
};
这也无法编译,因为现在 SomeOtherTypeWith16Alignment 不能按值传递,因为 _vectorcall 没有在构造函数上启用。
所以我只好改成这个了。
struct Vector{
Vector(const SomeOtherTypeWith16Alignment& a);
};
编译。但它不再使用 _vectorcall 并且可能不会像我希望的那样传递 SSE 寄存器中的数据......
那么基本上,为什么我不能指定构造函数使用的调用约定?
这可能是 Visual C++ 特定的(_vectorcall 肯定是)。我没有在其他编译器上试过这个--
【问题讨论】:
-
除非您在构造函数中进行计算,否则您不需要将其参数传递到寄存器中。如果将参数值存储在成员变量中,则无论如何它都不会存储在寄存器中。
-
嗨约阿希姆。在某些情况下,我正在构造函数中进行计算。例如,我有一个类型为 v4float,当用作寄存器时,它是一个 _m128 的包装器。还有另一种类型 v4float_memory 用于在寄存器之外进行存储。 v4float_memory 的构造函数接受 v4float。理想情况下,这应该在寄存器中传递,因为它在传入的数据上调用 _mm_store_ps。
-
并且编译器不会在需要时将其优化到寄存器中?你检查过生成的汇编代码吗?
-
我通过 __forceinlining 解决这个问题,希望编译器能够弄清楚实际上不是通过引用传递东西..
-
即使找到了解决方案,最初的问题也是有效的,我认为它仍然需要一个答案:“为什么不能为构造函数提及调用约定?”。
标签: c++ visual-c++ visual-studio-2013 simd calling-convention