ios scenekit arkit

ios - ¿Qué significa el prefijo "simd" en SceneKit?



arkit (2)

SIMD: datos múltiples de una sola instrucción

Las instrucciones SIMD le permiten realizar la misma operación en varios valores al mismo tiempo .

Veamos un ejemplo

Enfoque en serie (NO SIMD)

Tenemos estos 4 valores de Int32

let x0: Int32 = 10 let y0: Int32 = 20 let x1: Int32 = 30 let y1: Int32 = 40

Ahora queremos sumar los valores 2 x y 2 y , entonces escribimos

let sumX = x0 + x1 // 40 let sumY = y0 + y1 // 60

Para realizar las 2 sums anteriores, la CPU necesita

  1. carga x0 y x1 en la memoria y agrégalos
  2. carga y0 y y1 en la memoria y agrégalos

Así se obtiene el resultado con 2 operaciones.

He creado algunos gráficos para mostrarte mejor la idea.

Paso 1

Paso 2

SIMD

Veamos ahora cómo funciona SIMD. En primer lugar, necesitamos los valores de entrada almacenados en el formato adecuado de SIMD para

let x = simd_int2(10, 20) let y = simd_int2(30, 40)

Como se puede ver, los x y y son vectores. De hecho, tanto x como y contienen 2 componentes.

Ahora podemos escribir

let sum = x + y

Veamos qué hace la CPU para realizar las operaciones anteriores.

  1. carga xey en la memoria y agrégalos

¡Eso es!

Ambos componentes de x y ambos componentes de y se procesan al mismo tiempo .

Programación paralela

NO estamos hablando de programación concurrente, en lugar de eso, es una programación paralela real.

Como se puede imaginar en ciertas operaciones, el enfoque SIMD es mucho más rápido que el de serie.

Kit de escena

Veamos ahora un ejemplo en SceneKit.

Queremos agregar 10 a los componentes x , y , z de todos los descendientes directos del nodo de escena.

Usando el enfoque serial clásico podemos escribir

for node in scene.rootNode.childNodes { node.position.x += 10 node.position.y += 10 node.position.z += 10 }

Aquí se ejecuta un total de operaciones childNodes.count * 3 .

Veamos ahora cómo podemos convertir el código anterior en instrucciones SIMD.

let delta = simd_float3(10) for node in scene.rootNode.childNodes { node.simdPosition += delta }

Este código es mucho más rápido que el anterior. No estoy seguro de si es 2x o 3x más rápido pero, créeme, es mucho mejor.

Envolver

Si necesita realizar varias veces la misma operación en un valor diferente, solo use las propiedades SIMD :)

Existe una categoría de SCNNode llamada SCNNode(SIMD) , que declara algunas propiedades como simdPosition , simdRotation , etc. Parece que estas son propiedades duplicadas de la position y rotation propiedades originales / normales.

@property(nonatomic) simd_float3 simdPosition API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); @property(nonatomic) simd_float4 simdRotation API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));

¿Cuál es la diferencia entre la position y simdPosition ? ¿Qué significa exactamente el prefijo "simd"?


SIMD es una pequeña biblioteca construida sobre tipos de vectores que puede importar desde <simd/simd.h> . Permite un código más expresivo y de mayor rendimiento.

Por ejemplo usando SIMD puedes escribir

simd_float3 result = a + 2.0 * b;

en lugar de

SCNVector3 result = SCNVector3Make(a.x + 2.0 * b.x, a.y + 2.0 * b.y, a.z + 2.0 * b.z);

En Objective-C no puedes sobrecargar los métodos. Eso es que no puedes tener los dos.

@property(nonatomic) SCNVector3 position; @property(nonatomic) simd_float3 position API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));

La nueva API basada en SIMD necesitaba un nombre diferente, y es por eso que SceneKit expone simdPosition .