web-dev-qa-db-fra.com

Que signifie le préfixe "simd" dans SceneKit?

Il existe une catégorie SCNNode nommée SCNNode(SIMD), qui déclare certaines propriétés comme simdPosition, simdRotation et ainsi de suite. Il semble que ce soient des propriétés dupliquées des propriétés originales/normales position et rotation.

@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));

Quelle est la différence entre position et simdPosition? Que signifie exactement le préfixe "simd"?

22
ooOlly

SIMD: Single Instruction Multiple Data

Les instructions SIMD vous permettent d'effectuer la même opération sur plusieurs valeurs en même temps .

Voyons un exemple

Approche en série (PAS de SIMD)

Nous avons ces 4 valeurs Int32

let x0: Int32 = 10
let y0: Int32 = 20

let x1: Int32 = 30
let y1: Int32 = 40

Maintenant, nous voulons additionner les valeurs 2 x et 2 y, donc nous écrivons

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

Pour effectuer les 2 sums précédentes, le CPU doit

  1. charger x0 et x1 en mémoire et les ajouter
  2. charger y0 et y1 en mémoire et les ajouter

Le résultat est donc obtenu en 2 opérations.

J'ai créé des graphiques pour mieux vous montrer l'idée

Étape 1

enter image description here

Étape 2

enter image description here

SIMD

Voyons maintenant comment fonctionne SIMD. Tout d'abord, nous avons besoin des valeurs d'entrée stockées dans le format SIMD approprié afin

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

Comme vous pouvez le voir, les x et y précédents sont des vecteurs. En fait, x et y contiennent 2 composants.

Maintenant on peut écrire

let sum = x + y

Voyons ce que fait le CPU pour effectuer les opérations précédentes

  1. charger x et y en mémoire et les ajouter

enter image description here

C'est tout!

Les deux composants de x et les deux composants de y sont traités en même temps .

Programmation parallèle

Nous ne parlons [~ # ~] pas [~ # ~] de la programmation concurrente, mais plutôt réel parallèle programmation .

Comme vous pouvez l'imaginer dans certaines opérations, l'approche SIMD est beaucoup plus rapide que celle en série.

Kit de scène

Voyons maintenant un exemple dans SceneKit

Nous voulons ajouter 10 aux composants x, y et z de tous les descendants directs du nœud de scène.

En utilisant l'approche sérielle classique nous pouvons écrire

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

Voici un total de childNodes.count * 3 les opérations sont exécutées.

Voyons maintenant comment convertir le code précédent dans les instructions SIMD

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

Ce code est beaucoup plus rapide que le précédent. Je ne sais pas si 2x ou 3x plus vite mais, croyez-moi, c'est bien mieux.

Emballer

Si vous devez effectuer plusieurs fois la même opération sur une valeur différente, utilisez simplement les propriétés SIMD :)

58
Luca Angeletti

SIMD est une petite bibliothèque construite sur types de vecteurs que vous pouvez importer depuis <simd/simd.h>. Il permet un code plus expressif et plus performant.

Par exemple, en utilisant SIMD, vous pouvez écrire

simd_float3 result = a + 2.0 * b;

au lieu de

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

Dans Objective-C, vous ne pouvez pas surcharger les méthodes. Autrement dit, vous ne pouvez pas avoir les deux

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

La nouvelle API basée sur SIMD avait besoin d'un nom différent, et c'est pourquoi SceneKit expose simdPosition.

9
mnuages