nuget server logo nuget api documents
↑

API Docs / Microsoft.VisualBasic.Runtime / SimdMath

SimdMath

Full name Microsoft.VisualBasic.Math.SIMD.SimdMath Assembly Microsoft.VisualBasic.Runtime Members 27

单目(逐元素一元)向量化的数学函数。

00 Remarks

设计说明:只有存在对应硬件指令的运算才会被向量化。 SimdMath.Sqrt()/SimdMath.Abs()/SimdMath.Negate()/SimdMath.Square()/SimdMath.Clamp()/ SimdMath.Reciprocal() 都可以直接映射到 Vector 原语; 而 SimdMath.Exp() 与 SimdMath.Log() 在主流 x86/ARM 处理器上没有逐元素硬件指令 (仅 AVX-512 的 ER/PF 子集提供近似指令,且精度与可用性都不足以作为默认实现), 因此这两个函数保持与 Math 完全一致的标量实现,以保证数值结果的 确定性;对它们做“看似向量化”的多项式逼近会静默牺牲精度,这里不做这种取舍。

01 Syntax

Microsoft.VisualBasic.Math.SIMD.SimdMath

02 Methods

NameOverloadsSummary
Abs 1 逐元素绝对值:out(i) = |v(i)
Negate 1 逐元素取负:out(i) = -v(i)
Square 1 逐元素平方:out(i) = v(i) ^ 2
Sqrt 2 逐元素平方根(Double)。
Floor 2 逐元素向下取整(Double):out(i) = Floor(v(i))
Ceiling 2 逐元素向上取整(Double):out(i) = Ceiling(v(i))
Truncate 2 逐元素截断取整(Double):out(i) = Truncate(v(i))
Sign 2 逐元素符号函数(Double): out(i) = If(v(i) > 0, 1, If(v(i) < 0, -1, v(i)))
Reciprocal 2 逐元素倒数(Double):out(i) = 1 / v(i)
Clamp 1 逐元素区间钳制:out(i) = Min(Max(v(i), min), max)
Pow 1 逐元素幂运算:out(i) = v1(i) ^ v2(i)
PowScalar 1 以固定指数求幂:out(i) = v(i) ^ exponent
Exp 2 逐元素自然指数:out(i) = Exp(v(i))
Log 3 逐元素以 base 为底的对数:out(i) = Log(v(i), base)。
Abs 1
Negate 1
Square 1
Clamp 1

03 Members

method Abs #
Abs``1(``0())

逐元素绝对值:out(i) = |v(i)|

method Negate #
Negate``1(``0())

逐元素取负:out(i) = -v(i)

method Square #
Square``1(``0())

逐元素平方:out(i) = v(i) ^ 2

method Sqrt #
Sqrt(Double())

逐元素平方根(Double)。

method Sqrt overload 2 #
Sqrt(Single())

逐元素平方根(Single)。

method Floor #
Floor(Double())

逐元素向下取整(Double):out(i) = Floor(v(i))

Remarks

Vector.Floor 会由 JIT 映射到 SSE4.1 的 roundpd / AVX 的 vroundpd,或者 ARM64 的 frintm,语义与 Math.Floor() 完全一致。

method Floor overload 2 #
Floor(Single())

逐元素向下取整(Single)。

method Ceiling #
Ceiling(Double())

逐元素向上取整(Double):out(i) = Ceiling(v(i))

method Ceiling overload 2 #
Ceiling(Single())

逐元素向上取整(Single)。

method Truncate #
Truncate(Double())

逐元素截断取整(Double):out(i) = Truncate(v(i))

method Truncate overload 2 #
Truncate(Single())

逐元素截断取整(Single)。

method Sign #
Sign(Double())

逐元素符号函数(Double): out(i) = If(v(i) > 0, 1, If(v(i) < 0, -1, v(i)))

Remarks

“既不大于零也不小于零”的通道直接输出原始值,因此 +0.0 / -0.0 与 Double 的返回值与 Math.Sign() 保持一致(NaN 输入得到 NaN,而不是被静默变成 0)。

method Sign overload 2 #
Sign(Single())

逐元素符号函数(Single)。

method Reciprocal #
Reciprocal(Double())

逐元素倒数(Double):out(i) = 1 / v(i)

method Reciprocal overload 2 #
Reciprocal(Single())

逐元素倒数(Single):out(i) = 1 / v(i)

method Clamp #
Clamp``1(``0(), ``0, ``0)

逐元素区间钳制:out(i) = Min(Max(v(i), min), max)

Remarks

这个函数是手写展开的(而不是复用 SimdMath.Unary()), 以避免为了捕获 min / max 而产生闭包对象的堆分配。

method Pow #
Pow(Double(), Double())

逐元素幂运算:out(i) = v1(i) ^ v2(i)

Remarks

幂运算没有逐元素硬件指令(VB 的 ^ 会编译成 Math.Pow()),因此这里保持标量实现。 当指数是编译期可知的常量时,请优先使用 SimdMath.PowScalar() —— 它能够把 常见指数(2/3/4/0.5)特化为向量化的乘法与开方。

method PowScalar #
PowScalar(Double(), Double)

以固定指数求幂:out(i) = v(i) ^ exponent

Remarks

常见指数会被特化为向量化的乘法/开方:

其余指数退回标量 ^(与 VB 运算符语义完全一致)。

method Exp #
Exp(Double())

逐元素自然指数:out(i) = Exp(v(i))

Remarks

保持与 Math.Exp() 逐位一致的标量实现, 原因见类型备注(无可用硬件指令)。

method Exp overload 2 #
Exp(Single())

逐元素自然指数(Single)。

method Log overload 2 #
Log(Double())

逐元素自然对数:out(i) = Log(v(i))

Remarks

保持与 Math.Log() 逐位一致的标量实现。

method Log overload 3 #
Log(Single())

逐元素自然对数(Single)。

method Log #
Log(Double(), Double)

逐元素以 base 为底的对数:out(i) = Log(v(i), base)。

Remarks

等价于 Log(v(i)) / Log(base),与 Math.Log() 的实现方式一致。 其中除法部分可以向量化,对数的预算仍然是标量(无硬件指令)。

method Abs #
Abs(T())
method Negate #
Negate(T())
method Square #
Square(T())
method Clamp #
Clamp(T(), T, T)