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

时间:2016-08-04 17:26:57

标签: swift types metal

In Metal在packed_float4float4之间有什么区别?

2 个答案:

答案 0 :(得分:15)

此信息来自here

float4的{​​{1}}字节对齐。这意味着此类型的内存地址(例如16)将被0x12345670整除(也就是最后一个十六进制数字为16)。

另一方面,

0的对齐方式为packed_float4。地址的最后一位数字为4 bytes048

创建自定义结构时,这很重要。假设你想要一个包含2个普通c和1 float / float4的结构:

packed_float4

对于struct A{ float x, y; float4 z; } struct B{ float x, y; packed_float4 z; } A的对齐方式必须为float4,并且由于16必须位于正常的float4之后,所以float8之间的空格为y个字节。以下是z在内存中的样子:

A

对于 Address | 0x200 | 0x204 | 0x208 | 0x20c | 0x210 | 0x214 | 0x218 | 0x21c | Content | x | y | - | - | z1 | z2 | z3 | z4 | ^Has to be 16 byte aligned B的对齐方式为packed_float4,与4相同,因此在任何情况下都可以在float之后立即跟进:

float

如您所见, Address | 0x200 | 0x204 | 0x208 | 0x20c | 0x210 | 0x214 | Content | x | y | z1 | z2 | z3 | z4 | 占用A个字节,而32仅占用B个字节。当您拥有这些结构的数组时,24将为每个元素占用A个字节。因此,为了传递大量数据,后者是首选。

您需要8的原因是因为GPU无法处理float4字节对齐4,您无法返回{{} 1}}在着色器中。这是因为我假设的表现。

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

packed_float4

此结构将等于Metal中的packed_float4 not struct S { let x, y: Float let z : (Float, Float, Float, Float) } 。元组就像B

所有这些也适用于其他矢量类型,例如Apacked_floatN等。

答案 1 :(得分:-1)

我从the documentation收集的内容:

打包的数据类型是数组,而解压缩的计数器部分是结构。

这是他们的用法:

packed_float4 packedFloat4;
packedFloat4[0] = 0.0f;
packedFloat4[1] = 1.0f;
packedFloat4[2] = 2.0f;
packedFloat4[3] = 3.0f;

packed_float4 anotherPackedFloat4 = [0.0f, 1.0f, 2.0f, 3.0f] //array initalizer

//vs.

float4 f;
f.x = 0; //equivalent to f.r = 0;
f.y = 1; //equivalent to f.g = 1;
f.z = 2; //equivalent to f.b = 2;
f.w = 3; //equivalent to f.a = 3;

float4 anotherFloat4 = float4(0.0f, 1.0f, 2.0f, 3.0f) //constructor call