Scenedit中的"simd"前缀是什么意思?

ooO*_*lly 19 ios scenekit arkit

有一个SCNNode名为的类别SCNNode(SIMD),它声明了一些属性,如simdPosition,simdRotation等等.看来这些被复制的原始/正常性的性质positionrotation.

@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));
Run Code Online (Sandbox Code Playgroud)

position和之间有什么区别simdPosition?前缀"simd"到底意味着什么?

Luc*_*tti 54

SIMD:单指令多数据

SIMD指令允许你在执行多个值相同的操作同时.

我们来看一个例子吧

串行方法(无SIMD)

我们有这4个Int32值

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

let x1: Int32 = 30
let y1: Int32 = 40
Run Code Online (Sandbox Code Playgroud)

现在我们要总结2 x和2的y值,所以我们写

let sumX = x0 + x1 // 40
let sumY = y0 + y1 // 60
Run Code Online (Sandbox Code Playgroud)

为了执行前面sums的CPU需要的2

  1. 在内存中加载x0和x1并添加它们
  2. 在内存中加载y0和y1并添加它们

因此,结果是通过2次操作获得的.

我创建了一些图形来更好地向您展示这个想法

步骤1

在此输入图像描述

第2步

在此输入图像描述

SIMD

现在让我们看看SIMD是如何工作的.首先,我们需要以适当的SIMD格式存储输入值

let x = simd_int2(10, 20)
let y = simd_int2(30, 40)
Run Code Online (Sandbox Code Playgroud)

正如你可以看到前面的x并且y是向量.事实上x,y 包含2个组件.

现在我们可以写了

let sum = x + y
Run Code Online (Sandbox Code Playgroud)

让我们看看CPU为执行先前的操作所做的工作

  1. 在内存中加载x和y并添加它们

在此输入图像描述

而已!

的两个分量x的两个分量和y同时处理.

并行编程

我们不是在谈论并发编程,而是真正的并行编程.

正如您在某些操作中可以想象的那样,SIMD方法比串行方法快.

场景套件

现在让我们看一下SceneKit中的一个例子

我们要添加10x,yz现场节点的所有直系后裔的组成部分.

使用经典的串行方法我们可以编写

for node in scene.rootNode.childNodes {
    node.position.x += 10
    node.position.y += 10
    node.position.z += 10
}
Run Code Online (Sandbox Code Playgroud)

这里childNodes.count * 3执行了总共操作.

现在让我们看看如何在SIMD指令中转换以前的代码

let delta = simd_float3(10)
for node in scene.rootNode.childNodes {
    node.simdPosition += delta
}
Run Code Online (Sandbox Code Playgroud)

此代码比前一代码快得多.我不确定2倍或3倍的速度,但相信我,它会更好.

包起来

如果您需要对不同的值执行多次相同的操作,只需使用SIMD属性:)

  • 精彩的解释!非常感谢. (6认同)
  • 这大多是正确的,但并不完全是问题的核心.不仅SIMD库中的类型为向量加法等操作提供了方便的语法(毕竟,在Swift中,至少通过扩展`SCNVector3`可以很容易地做到这一点).该库还可以使用特定于CPU的向量指令(在ARM和x86上)快速实现此类操作.它为多个框架使用的矢量和矩阵提供了一个共享的"词汇表",包括ARKit,GameplayKit,Model I/O和Metal shader语言. (2认同)

mnu*_*ges 7

SIMD是一个基于矢量类型构建的小型库,您可以从中导入<simd/simd.h>.它允许更具表现力和更高性能的代码.

例如,使用SIMD,你可以写

simd_float3 result = a + 2.0 * b;
Run Code Online (Sandbox Code Playgroud)

代替

SCNVector3 result = SCNVector3Make(a.x + 2.0 * b.x, a.y + 2.0 * b.y, a.z + 2.0 * b.z);
Run Code Online (Sandbox Code Playgroud)

在Objective-C中,您不能重载方法.那就是你不能兼得

@property(nonatomic) SCNVector3 position;
@property(nonatomic) simd_float3 position API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));
Run Code Online (Sandbox Code Playgroud)

新的基于SIMD的API需要一个不同的名称,这就是SceneKit公开的原因simdPosition.