这篇翻译不完整。请帮忙从英语翻译这篇文章

SIMD.js已经从TC39的发展中主动脱离出来了,并在第三阶段移除。web浏览器不再追求它的实现。SIMD操作暴露在web上,在WebAssembly中处于积极的开发状态,操作基于SIMD.js操作。

SIMD (发音为 "sim-dee") 是 Single Instruction/Multiple Data(单指令流/多数据流) 的缩写。其为计算机体系结构的一种分类。SIMD操作在多个数据点上执行相同的计算,因此实现了数据级别的并行性,从而提高性能,例如用于3D图形和视频处理、物理模拟或密码学以及其他领域。

此页面及其子页面是 SIMD API 的参考文档。参考 SIMD types,这篇文章讲述了更多关于 JavaScript 中的 SIMD。

描述

JavaScript SIMD API由几种新类型和操作组成。根据用户的底层硬件,浏览器提供了该API的高度优化的实现。现在,SIMD 特别为 ARMv7 platforms with NEON 和 x86 platforms with SSE 建立了模型。

SIMD API类型安装在 SIMD 模块上。与其他全局对象不同,SIMD 不是构造函数。你不能用它来使用一个 new 运算符或者把 SIMD 对象当作一个函数调用。SIMD 的所有属性和方法都是静态的(就像Math对象的情况一样)。

概览

SIMD 值有多个通道。对于长度为4的向量,这些通道被命名为x, y, z, 和 w。现在,不必在4个通道上分别执行单独的操作,SIMD允许您同时在所有4个通道上执行操作。这需要更少的操作,这与标量操作(SISD)相比,将带来性能上的改善,更优的能源效率。请注意,SIMD操作不能用于以不同的方式处理多个数据。在下图中,只有一个指令(加法),因此可以使用SIMD操作:

SISD SIMD

图 1 和 2: SISD 和 SIMD 对比。

简单的加法算术运算

像图 2 中简单的 SIMD 操作,其 JavaScript 代码如下所示:

var a = SIMD.Float32x4(1, 2, 3, 4);
var b = SIMD.Float32x4(5, 6, 7, 8);
var c = SIMD.Float32x4.add(a,b); // Float32x4[6,8,10,12]

数据类型

所有SIMD数据类型都是不可变的。你不能直接改变它们。相反,您执行的操作创建了新的不可变 SIMD 数据类型。
下图显示了 128 位 SIMD 寄存器中不同的 SIMD 数据类型。当前的 SIMD JavaScript API 有 12 种不同的类型,每种类型的通道长度为2、4、8或16。

Lanes per type in a 128-bit SIMD register

图 3 :128 位 SIMD 寄存器中每种类型的通道

SIMD 布尔类型

SIMD.Bool8x16
128位被划分为16个存储布尔值的通道。
SIMD.Bool16x8
128位被划分为8个存储布尔值的通道。
SIMD.Bool32x4
128位被划分为4个存储布尔值的通道。
SIMD.Bool64x2
128位被划分为2个存储布尔值的通道。

SIMD 有符号整数类型

SIMD.Int8x16
128位被划分为16个通道,每个通道存储8位有符号整数值。
SIMD.Int16x8
128位被划分为8个通道,每个通道存储16位有符号整数值。
SIMD.Int32x4
128位被划分为4个通道,每个通道存储32位有符号整数值。

SIMD 无符号整数类型

SIMD.Uint8x16
128位被划分为16个通道,每个通道存储8位无符号整数值。
SIMD.Uint16x8
128位被划分为8个通道,每个通道存储16位无符号整数值。
SIMD.Uint32x4
128位被划分为4个通道,每个通道存储32位无符号整数值。

SIMD 浮点数类型

SIMD.Float32x4
128位被划分为4个通道,每个通道存储一个单精度浮点数值。
SIMD.Float64x2
128位被划分为2个通道,每个通道存储一个双精度浮点数值。

构造函数

 

除了简单的函数之外(e.g. SIMD.Int32x4(1,2,3,4)),SIMD API还提供了以下构造函数:

SIMD.%type%.splat()
创建一个 SIMD 数据类型,所有的通道都设置为给定的值。

 

你还可以 从一种 SIMD 数据类型转换到另一种.

Note: SIMD 类型使用 new 声明不会生效,因为 SIMD 值不是 "盒内" 对象 (好比 String(s) 和 new String(s), 后者创建了一个字符串对象)。

var v = new SIMD.Float32x4(0,1,2,3);
// TypeError: SIMD.Float32x4 is not a constructor

相反,你只需这样写:

var v = SIMD.Float32x4(0,1,2,3);

操作

要用 SIMD 类型做一些事情,在 SIMD data 数据类型之上的 SIMD 操作是必须的。

Note: 不是所有的 SIMD 都具有全部的 SIMD 操作,查看各自的参考页面获取可用性和相关细节。

检查 SIMD 类型

SIMD.%type%.check()
如果参数是有效的 SIMD 数据类型,则返回一个与  %type% 类型相同的实例。否则抛出一个 TypeError

访问和修改通道

SIMD.%type%.extractLane()
返回给定通道的值。
SIMD.%type%.replaceLane()
替换给定通道的值并返回一个新的实例。

对类型数组进行存取

SIMD.%type%.load()
SIMD.%type%.load1()
SIMD.%type%.load2()
SIMD.%type%.load3()
根据从 类型数组 加载的通道值,返回一个新的实例。
SIMD.%type%.store()
SIMD.%type%.store1()
SIMD.%type%.store2()
SIMD.%type%.store3()
将一个 SIMD 数据类型存储到 类型数组

算术运算

SIMD.%FloatType%.abs()
返回一个新的实例,其值为通道值的绝对值。
SIMD.%type%.add()
返回一个新的实例,其值为通道值相加 (a + b).
SIMD.%type%.addSaturate()
返回一个新的实例,其值为通道值相加 (a + b) ,溢出时会饱和。
SIMD.%FloatType%.div()
返回一个新的实例,其值为通道值相除 (a / b).
SIMD.%type%.mul()
返回一个新的实例,其值为通道值相乘 (a * b).
SIMD.%type%.neg()
返回一个新的实例,其值为通道值取反。
SIMD.%FloatType%.reciprocalApproximation()
返回一个新的实例,其值为通道值倒数的近似值。
SIMD.%FloatType%.reciprocalSqrtApproximation()
返回一个新的实例,其值为通道值平方根倒数的近似值。
SIMD.%type%.sub()
返回一个新的实例,其值为通道值相减 (a - b).
SIMD.%type%.subSaturate()
返回一个新的实例,其值为通道值相减 (a - b) ,溢出时会饱和。
SIMD.%FloatType%.sqrt()
返回一个新的实例,其值为通道值的平方根。

Shuffling and swizzling

SIMD.%type%.shuffle()
返回一个新的实例,其值为 the lane values shuffled.
SIMD.%type%.swizzle()
返回一个新的实例,其值为 the lane values swizzled.

最小值和最大值

SIMD.%FloatType%.max()
返回一个新的实例,其值为 the maximum of the lane values.
SIMD.%FloatType%.maxNum()
返回一个新的实例,其值为 the maximum of the lane values, preferring numbers over NaN.
SIMD.%FloatType%.min()
返回一个新的实例,其值为 the minimum of the lane values.
SIMD.%FloatType%.minNum()
返回一个新的实例,其值为 the minimum of the lane values, preferring numbers over NaN.

选择

SIMD.%type%.select()
返回一个新的实例,其值为 the lane values being a mix of the lanes depending on the selector mask.

比较

SIMD.%type%.equal()
根据 a == b 返回一个选择掩码。
SIMD.%type%.notEqual()
根据 a != b 返回一个选择掩码。
SIMD.%type%.lessThan()
根据 a < b 返回一个选择掩码。
SIMD.%type%.lessThanOrEqual()
根据 a <= b 返回一个选择掩码。
SIMD.%type%.greaterThan()
根据 a > b 返回一个选择掩码。
SIMD.%type%.greaterThanOrEqual()
根据 a >=  返回一个选择掩码。

位逻辑运算

SIMD.%type%.and()
返回一个新的实例,其值为通道值逻辑与 (a & b).
SIMD.%type%.or()
返回一个新的实例,其值为通道值逻辑或 (a | b).
SIMD.%type%.xor()
返回一个新的实例,其值为通道值逻辑异或 (a ^ b).
SIMD.%type%.not()
返回一个新的实例,其值为通道值逻辑非(~a).

移位操作

SIMD.%IntegerType%.shiftLeftByScalar()
返回一个新的实例,其值为通道值左移给定位数 (a << bits).
SIMD.%IntegerType%.shiftRightByScalar()
返回一个新的实例,其值为通道值右移给定位数。行为取决于基本类型是有符号的还是无符号的。

布尔运算

SIMD.%BooleanType%.allTrue()
检查是否所有的通道都为 true 值.
SIMD.%BooleanType%.anyTrue()
检查是否存在通道为 true 值。

数据转换

SIMD.%type%.fromFloat32x4()
Creates a new SIMD data type with a float conversion from a Float32x4.
SIMD.%type%.fromFloat32x4Bits()
Creates a new SIMD data type with a bit-wise copy from a Float32x4.
SIMD.%type%.fromFloat64x2Bits()
Creates a new SIMD data type with a bit-wise copy from a Float64x2.
SIMD.%type%.fromInt32x4()
Creates a new SIMD data type with an integer conversion from an In32x4.
SIMD.%type%.fromInt32x4Bits()
Creates a new SIMD data type with a bit-wise copy from an Int32x4.
SIMD.%type%.fromInt16x8Bits()
Creates a new SIMD data type with a bit-wise copy from an Int16x8.
SIMD.%type%.fromInt8x16Bits()
Creates a new SIMD data type with a bit-wise copy from an Int8x16.
SIMD.%type%.fromUint32x4()
Creates a new SIMD data type with an integer conversion from a Uin32x4.
SIMD.%type%.fromUint32x4Bits()
Creates a new SIMD data type with a bit-wise copy from a Uint32x4.
SIMD.%type%.fromUint16x8Bits()
Creates a new SIMD data type with a bit-wise copy from a Uint16x8.
SIMD.%type%.fromUint8x16Bits()
Creates a new SIMD data type with a bit-wise copy from a Uint8x16.

SIMD 原型

下面的方法和属性都位于 SIMD.%type%.prototype

SIMD.%type%.prototype.constructor
指定创建一个 SIMD 对象原型的函数。
SIMD.%type%.prototype.toLocaleString()
返回一个表示SIMD类型及其元素的本地化字符串。覆盖Object.prototype.toLocaleString() 方法。
SIMD.%type%.prototype.toString()
返回一个表示SIMD类型及其元素的字符串。覆盖 Object.prototype.toString() 方法。
SIMD.%type%.prototype.valueOf()
返回 SIMD 对象的原始值。
SIMD.%type%.prototype.toSource()
返回一个表示对象源代码的字符串。覆盖Object.prototype.toSource() 方法。

Polyfill

A Polyfill implementation based on typed arrays, is available at the ecmascript_simd GitHub repository.

规范

规范 状态 说明
SIMD
SIMD
Obsolete 首次定义

浏览器兼容性

实验性的 SIMD.js 已经从浏览器中移除。但它仍然可以在 Firefox Nightly 中使用, 但是会被移除,取而代之的是 WebAssembly中的 SIMD 实现。参考 bug 1416723.

相关链接

文档标签和贡献者

此页面的贡献者: codeofjackie, fscholz
最后编辑者: codeofjackie,