SceneKit 中的“simd”前缀是啥意思?

Posted

技术标签:

【中文标题】SceneKit 中的“simd”前缀是啥意思?【英文标题】:What does the "simd" prefix mean in SceneKit?SceneKit 中的“simd”前缀是什么意思? 【发布时间】:2017-11-29 02:59:44 【问题描述】:

有一个名为SCNNode(SIMD)SCNNode 类别,它声明了一些属性,如simdPositionsimdRotation 等。这些似乎是原始/普通属性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));

positionsimdPosition 有什么区别?前缀“simd”到底是什么意思?

【问题讨论】:

en.wikipedia.org/wiki/SIMD 我也有同样的疑惑:***.com/questions/44732476/… 不完全重复,但另见this answer。 【参考方案1】:

SIMD:单指令多数据

SIMD 指令允许您同时对多个值执行相同的操作。

我们来看一个例子

串行方法(无 SIMD)

我们有这 4 个 Int32 值

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

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

现在我们要将 2 个 x 和 2 个 y 值相加,所以我们写

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

为了执行前两个sums,CPU 需要

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

所以结果是通过2次操作得到的。

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

第一步

第 2 步

SIMD

现在让我们看看 SIMD 是如何工作的。 首先,我们需要以正确的 SIMD 格式存储输入值,所以

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

如您所见,前面的 xy 是向量。事实上,xy 都包含 2 个组件。

现在我们可以写了

let sum = x + y

让我们看看 CPU 做了什么来执行前面的操作

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

就是这样!

x 的两个组件和y 的两个组件同时处理

并行编程

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

您可以想象,在某些操作中,SIMD 方法比串行方法快得多。

场景套件

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

我们希望将10 添加到场景节点的所有直系后代的xyz 组件中。

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

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

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

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

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

这段代码比前一个要快得多。我不确定是快 2 倍还是 3 倍,但相信我,这要好得多。

总结

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

【讨论】:

精彩的解释!非常感谢。 这大部分是正确的,但并没有完全解决问题的核心。不仅仅是 SIMD 库中的类型为向量加法等操作提供了方便的语法(毕竟,在 Swift 中,至少通过扩展 SCNVector3 很容易做到这一点)。该库还用于使用特定于 CPU 的向量指令(在 ARM 和 x86 上)提供此类操作的快速实现。它还为向量和矩阵提供了一个共享的“词汇表”,供多个框架使用,包括 ARKit、GameplayKit、模型 I/O 和 Metal 着色器语言。 嘿@Luca,非常感谢您的详细回答!我和我的团队在一个问题上停留了好几天啊:/我发布了一个有趣的问题:***.com/questions/63662318/…希望您提出建议!【参考方案2】:

SIMD 是一个建立在vector types 之上的小型库,您可以从<simd/simd.h> 导入它。它允许更富有表现力和更高性能的代码。

例如使用 SIMD 你可以写

simd_float3 result = a + 2.0 * b;

而不是

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

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

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

【讨论】:

很好的答案,很有道理。

以上是关于SceneKit 中的“simd”前缀是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

cookie 域中的点前缀是啥意思?

macOS pluginkit 输出中的前缀是啥意思?

AWS ELB 中的双栈前缀是啥意思?

“__cxa_demangle”中的“cxa”前缀是啥意思?

MS Access SQL 查询中的这个前缀 (ABF:) 是啥意思?

NS前缀是啥意思?