单目(逐元素一元)向量化的数学函数。
SimdMath
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
02 Methods
| Name | Overloads | Summary |
|---|---|---|
| Abs | 1 | 逐元素绝对值:out(i) = |v(i) |
| Negate | 1 | 逐元素取负:out(i) = -v(i) |
| Square | 1 | 逐元素平方:out(i) = v(i) ^ 2 |
| Sqrt | 2 | 逐元素平方根(Double)。 |
| 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 | 2 | 逐元素自然对数:out(i) = Log(v(i)) |
| Abs | 1 | |
| Negate | 1 | |
| Square | 1 | |
| Clamp | 1 |
03 Members
``0())逐元素绝对值:out(i) = |v(i)|
``0())逐元素取负:out(i) = -v(i)
``0())逐元素平方:out(i) = v(i) ^ 2
Double())逐元素平方根(Double)。
Single())逐元素平方根(Single)。
Double())逐元素倒数(Double):out(i) = 1 / v(i)
Single())逐元素倒数(Single):out(i) = 1 / v(i)
``0(), ``0, ``0)逐元素区间钳制:out(i) = Min(Max(v(i), min), max)
这个函数是手写展开的(而不是复用 SimdMath.Unary()), 以避免为了捕获 min / max 而产生闭包对象的堆分配。
Double(), Double())逐元素幂运算:out(i) = v1(i) ^ v2(i)
幂运算没有逐元素硬件指令(VB 的 ^ 会编译成 Math.Pow()),因此这里保持标量实现。 当指数是编译期可知的常量时,请优先使用 SimdMath.PowScalar() —— 它能够把 常见指数(2/3/4/0.5)特化为向量化的乘法与开方。
Double(), Double)以固定指数求幂:out(i) = v(i) ^ exponent
常见指数会被特化为向量化的乘法/开方:
0→ 常量 11→ 直接拷贝2→ SimdMath.Square()3→v * v * v4→ 连续两次 SimdMath.Square()0.5→ SimdMath.Sqrt()
其余指数退回标量 ^(与 VB 运算符语义完全一致)。
Double())逐元素自然指数:out(i) = Exp(v(i))
保持与 Math.Exp() 逐位一致的标量实现, 原因见类型备注(无可用硬件指令)。
Single())逐元素自然指数(Single)。
Double())逐元素自然对数:out(i) = Log(v(i))
保持与 Math.Log() 逐位一致的标量实现。
Single())逐元素自然对数(Single)。
T())T())T())T(), T, T)