【问题标题】:Passing types containing SSE/AVX values传递包含 SSE/AVX 值的类型
【发布时间】:2011-12-12 18:13:21
【问题描述】:

假设我有以下内容

struct A
{
    __m256 a;
}
struct B
{
    __m256 a;
    float b;
}

在硬核循环中,以下哪项通常更好(如果有,为什么)?

void f0(A a) { ... }
void f1(A& a) { ... } //and the pointer variation
void f2(B b) { ...}
void f3(B& b) { ... } //and the pointer variation

【问题讨论】:

    标签: c++ visual-c++ optimization sse avx


    【解决方案1】:

    答案是没关系。

    据此:

    http://msdn.microsoft.com/en-us/library/ms235286.aspx

    调用约定规定 16 字节(也可能是 32 字节)操作数始终通过引用传递。所以即使你按值传递,编译器也会在下面通过引用传递。

    换句话说,XMM 和 YMM 寄存器在 Windows 中永远不会按值传递。但是XMM0-4的下半部分仍然可以用来传值的64位参数。

    编辑:

    在您使用 float 值的第二个示例中,存在细微差别,因为它仍然会影响 b 是通过引用传递还是通过值传递。

    【讨论】:

    • 你可以通过 val 和 ref 传递结构的一部分吗?我以为你必须通过 ref (指向堆栈/堆的指针)或 val (复制到堆栈)整个事情?
    • 从性能方面来说,主要是参数是栈传还是寄存器传。 64 位或更小的值传递参数由寄存器完成或复制到堆栈。 (我不完全确定这是否也适用于结构,因为每个成员都可以被视为单独的参数。)通过引用传递参数通常通过传递指向参数的指针来完成 - 这对于所有较大的参数都是必需的超过 64 位。
    • 所以我的意思是,无论你做什么,XMM 和 YMM 值都不会在 Windows 中通过寄存器传递。 (除非您启用了 IPO 或函数被内联或其他)
    • 谢谢,我明白了。我不知道结构成员被有效地视为单独的参数(按值传递时)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 2013-03-21
    • 2018-01-04
    • 1970-01-01
    相关资源
    最近更新 更多