2016-08-04 4 views
4

В Металле какая разница между packed_float4 и float4?Разница между упакованным и нормальным типом данных

+0

https://developer.apple.com/library/ios/documentation/Metal/Reference/MetalShadingLanguageGuide/data-types/data-types.html – FredericP

+1

Я прочитал эту документацию. Он не говорит вам, что такое упакованный тип данных. Он просто раскрывает, что они доступны в Metal. – gloo

ответ

10

Эта информация от here

float4 имеет выравнивание 16 байт. Это означает, что адрес памяти такого типа (например, 0x12345670) будет делиться на 16 (также как и последняя шестнадцатеричная цифра 0).

packed_float4 С другой стороны, имеет значение 4 bytes. Последняя цифра адреса будет 0, 4, 8 или c

Это имеет значение при создании пользовательских структур. Допустим, вы хотите-структуру с 2 нормальных float с и 1 float4/packed_float4:

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

struct B{ 
    float x, y; 
    packed_float4 z; 
} 

Для A: Выравнивание float4 должен быть 16 и так float4 должен быть после нормальных float с, что собирается be 8 байт пустого пространства между 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 больше байтов для каждого элемента. Поэтому для передачи большого количества данных последнее предпочтительнее.

Причина вам нужно float4 на все, потому что ГПУ не может обрабатывать 4 байт выровнены packed_float4 с, вы не сможете вернуть packed_float4 в затенении. Это из-за производительности, которую я предполагаю.

Одна последняя вещь: Когда вы объявляете Swift версию структуры:

struct S { 
    let x, y: Float 
    let z : (Float, Float, Float, Float) 
} 

Эта структура будет равна B в металле и неA. Кортеж похож на packed_floatN.

Все это относится также к другим типам векторов, таким как packed_float3, packed_short2, ect.

+1

Этот ответ лучше, чем принятый ответ. – warrenm

+0

На самом деле, это научило меня много. –

+0

Это на самом деле правильный ответ. –

-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 
+1

Это неправильный ответ. Основное различие заключается в размере и выравнивании в памяти. –

+0

@ DalijaPrasnikar OP попросил разницу между ними, и я дал правильный ответ на их разницу, как кажется потребителю API. Если вы ответите на дальнейшие разногласия, я с радостью продолжу это. – Alexander

+0

Вы дали половину ответа. Struct vs array - это просто побочный эффект реальной причины, по которой эти два типа существуют, и различия в функциональности и использовании. –

Смежные вопросы