[英]Difference between packed vs normal data type
在Metal中, packed_float4
和float4
什么区别?
This information is from here 此信息来自此处
float4
has an alignment of 16
bytes. float4
的对齐方式为16
个字节。 This means that the memory address of such a type (eg 0x12345670
) will be divisible by 16
(aka the last hexadecimal digit is 0
). 这意味着这种类型的存储器地址(例如
0x12345670
)将被16
整除(也就是最后的十六进制数字是0
)。
packed_float4
on the other hand has an alignment of 4 bytes
. 另一方面,
packed_float4
具有4 bytes
的对齐。 Last digit of the address will be 0
, 4
, 8
or c
地址的最后一位将是
0
, 4
, 8
或c
This does matter when you create custom structs. 这在创建自定义结构时很重要。 Say you want a struct with 2 normal
float
s and 1 float4
/ packed_float4
: 假设您想要一个包含2个普通
float
和1个float4
/ packed_float4
:
struct A{
float x, y;
float4 z;
}
struct B{
float x, y;
packed_float4 z;
}
For A
: The alignment of float4
has to be 16
and since float4
has to be after the normal float
s, there is going to be 8
bytes of empty space between y
and z
. 对于
A
: float4
的对齐必须是16
,因为float4
必须在正常的float
之后,所以y
和z
之间将有8
个字节的空白。 Here is what A
looks like in memory: 这是
A
在内存中A
样子:
Address | 0x200 | 0x204 | 0x208 | 0x20c | 0x210 | 0x214 | 0x218 | 0x21c |
Content | x | y | - | - | z1 | z2 | z3 | z4 |
^Has to be 16 byte aligned
For B
: Alignment of packed_float4
is 4
, the same as float
, so it can follow right after the float
s in any case: 对于
B
: packed_float4
对齐是4
,与float
相同,所以在任何情况下它都可以紧跟在float
之后:
Address | 0x200 | 0x204 | 0x208 | 0x20c | 0x210 | 0x214 |
Content | x | y | z1 | z2 | z3 | z4 |
As you can see, A
takes up 32
bytes whereas B
only uses 24
bytes. 如您所见,
A
占用32
个字节,而B
仅占用24
个字节。 When you have an array of those structs, A
will take up 8
more bytes for every element. 如果有这些结构的数组,
A
将为每个元素占用8
个字节。 So for passing around a lot of data, the latter is preferred. 因此,为了传递大量数据,后者是首选。
The reason you need float4
at all is because the GPU can't handle 4
byte aligned packed_float4
s, you won't be able to return packed_float4
in a shader. 你需要
float4
的原因是因为GPU无法处理4
字节对齐的packed_float4
,你将无法在着色器中返回packed_float4
。 This is because of performance I assume. 这是因为我假设的表现。
One last thing: When you declare the Swift version of a struct: 最后一件事:当你声明一个结构的Swift版本时:
struct S {
let x, y: Float
let z : (Float, Float, Float, Float)
}
This struct will be equal to B
in Metal and not A
. 此结构将等于Metal中的
B
而不是 A
A tuple is like a packed_floatN
. 元组就像
packed_floatN
。
All of this also applies to other vector types such as packed_float3
, packed_short2
, ect. 所有这些也适用于其他矢量类型,如
packed_float3
, packed_short2
等。
From what I gather from the documentation : 从我从文档中收集的内容 :
Packed datatypes are arrays, whereas their unpacked counter parts are structs. 打包的数据类型是数组,而解压缩的计数器部分是结构。
Here's their usage: 这是他们的用法:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.