打包与普通数据类型的区别

glo*_*loo 8 types swift metal

在金属中a packed_float4和a有float4什么区别?

Sil*_*ger 19

此信息来自此处

float4具有16字节对齐.这意味着这种类型(例如0x12345670)的存储器地址将被整除16(也就是最后的十六进制数字0).

packed_float4另一方面有一个对齐4 bytes.地址的最后一位将是0,4,8或者c

这在创建自定义结构时很重要.假设您想要一个具有2个普通floats和1 float4/的结构packed_float4:

struct A{
    float x, y;
    float4 z;
}

struct B{
    float x, y;
    packed_float4 z;
}
Run Code Online (Sandbox Code Playgroud)

A:所述的对准float4必须是16并且由于float4必须是正常的之后floats时,将是8之间空的空间字节yz.这是A内存中的样子:

 Address | 0x200 | 0x204 | 0x208 | 0x20c | 0x210 | 0x214 | 0x218 | 0x21c |
 Content |   x   |   y   |   -   |   -   |   z1  |   z2  |   z3  |   z4  |
                                             ^Has to be 16 byte aligned
Run Code Online (Sandbox Code Playgroud)

对于B:对齐packed_float44,相同float,所以它可以在floats 之后跟随任何情况:

 Address | 0x200 | 0x204 | 0x208 | 0x20c | 0x210 | 0x214 |
 Content |   x   |   y   |   z1  |   z2  |   z3  |   z4  |
Run Code Online (Sandbox Code Playgroud)

如您所见,A占用32字节而B仅使用24字节.当你有这些结构的数组时,每个元素A将占用8更多的字节.因此,为了传递大量数据,后者是首选.

您需要的原因float4是因为GPU无法处理4字节对齐的packed_float4s,您将无法packed_float4在着色器中返回.这是因为我假设的表现.

最后一件事:当你声明一个结构的Swift版本时:

struct S {
    let x, y: Float
    let z : (Float, Float, Float, Float)
}
Run Code Online (Sandbox Code Playgroud)

此结构将等于BMetal中的结构而不是 A.元组就像一个packed_floatN.

所有这些也适用于其他矢量类型,例如packed_float3,packed_short2等.