What does the “simd” prefix mean in SceneKit?

后端 未结 2 541
鱼传尺愫
鱼传尺愫 2020-12-13 05:17

There is a SCNNode category named SCNNode(SIMD), which declares some properties like simdPosition, simdRotation and so on

相关标签:
2条回答
  • 2020-12-13 05:36

    SIMD is a small library built on top of vector types that you can import from <simd/simd.h>. It allows for more expressive and more performant code.

    For instance using SIMD you can write

    simd_float3 result = a + 2.0 * b;
    

    instead of

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

    In Objective-C you can not overload methods. That is you can not have both

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

    The new SIMD-based API needed a different name, and that's why SceneKit exposes simdPosition.

    0 讨论(0)
  • 2020-12-13 05:45

    SIMD: Single Instruction Multiple Data

    SIMD instructions allow you to perform the same operation on multiple values at the same time.

    Let's see an example

    Serial Approach (NO SIMD)

    We have these 4 Int32 values

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

    Now we want to sum the 2 x and the 2 y values, so we write

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

    In order to perform the 2 previous sums the CPU needs to

    1. load x0 and x1 in memory and add them
    2. load y0 and y1 in memory and add them

    So the result is obtained with 2 operations.

    I created some graphics to better show you the idea

    Step 1

    Step 2

    SIMD

    Let's see now how SIMD does work. First of all we need the input values stored in the proper SIMD format so

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

    As you can see the previous x and y are vectors. Infact both x and y contain 2 components.

    Now we can write

    let sum = x + y
    

    Let's see what the CPU does in order to perform the previous operations

    1. load x and y in memory and add them

    That's it!

    Both components of x and both components of y are processed at the same time.

    Parallel Programming

    We are NOT talking about concurrent programming, instead this is real parallel programming.

    As you can imagine in certain operation the SIMD approach is way faster then the serial one.

    Scene Kit

    Let's see now an example in SceneKit

    We want to add 10 to the x, y and z components of all the direct descendants of the scene node.

    Using the classic serial approach we can write

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

    Here a total of childNodes.count * 3 operations is executed.

    Let's see now how we can convert the previous code in SIMD instructions

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

    This code is much faster then the previous one. I am not sure whether 2x or 3x faster but, believe me, it's way better.

    Wrap up

    If you need to perform several times the same operation on different value, just use the SIMD properties :)

    0 讨论(0)
提交回复
热议问题