归约运算(把整个向量折叠成一个标量)。
SimdReduce
00 Remarks
与 SimdEngine 不同,这里的函数会校验输入长度并抛出 ArgumentException:归约运算的长度不一致是调用方的逻辑错误, 静默截断只会带来更难定位的数值 bug。
求和/点积类内核使用 4 路累加器来打断浮点加法的依赖链(vaddpd 的 延时大约是 3~4 个周期,单累加器会让吞吐被延时吃满),在长数组上可以拿到 接近 4 倍的额外提升。
01 Syntax
02 Methods
| Name | Overloads | Summary |
|---|---|---|
| Sum | 2 | 求和:SUM(v)。空数组返回 0。 |
| SumScalar | 1 | 单线程标量求和(同时用作纯标量回退路径)。 |
| SumSquares | 1 | 平方和:SUM(v(i) ^ 2)。空数组返回 0。 |
| Dot | 2 | 点积:SUM(v1(i) * v2(i))。 |
| Min | 2 | 求 [start, ends) 区间(前闭后开)的最小值。 |
| Max | 3 | 求 [start, ends) 区间(前闭后开)的最大值。 |
| MaxAbs | 2 | 求 [start, ends) 区间(前闭后开)的绝对值最大值。空区间返回 0。 |
| Mean | 2 | 均值:SUM(v) / N。空数组会抛出 ArgumentException。 |
| L1Norm | 2 | 求 [start, ends) 区间(前闭后开)的 L1 范数。 |
| L2Norm | 1 | L2 范数(欧几里得范数):SQRT(SUM(v(i) ^ 2))。空数组返回 0。 |
| ArgMax | 1 | 最大值所在的下标(第一个匹配项)。空数组会抛出 ArgumentException。 |
| ArgMin | 1 | 最小值所在的下标(第一个匹配项)。空数组会抛出 ArgumentException。 |
03 Members
Double())求和:SUM(v)。空数组返回 0。
Single())求和:SUM(v)。空数组返回 0。
Double(), Int32, Int32)单线程标量求和(同时用作纯标量回退路径)。
Double())平方和:SUM(v(i) ^ 2)。空数组返回 0。
Double(), Double())点积:SUM(v1(i) * v2(i))。
这个实现不使用 FMA 指令(以保持与 SIMDIntrinsics.DotFma() 的依赖方向单纯,避免相互递归);需要 FMA 版本请直接调用 SIMDIntrinsics.DotFma(), 它会在这个实现之上自动选择更快的路径。
Single(), Single())点积:SUM(v1(i) * v2(i)),累加结果为 Double。
Double())最小值。空数组会抛出 ArgumentException。
Double(), Int32, Int32)求 [start, ends) 区间(前闭后开)的最小值。
Double())最大值。空数组会抛出 ArgumentException。
Double(), Int32, Int32)求 [start, ends) 区间(前闭后开)的最大值。
Single())最大值。空数组会抛出 ArgumentException。
Double())绝对值最大值:MAX(|v(i)|)。空数组返回 0。
这个内核用于数值稳定算法中的缩放因子探测(例如 Frobenius 范数的抗上溢处理), 与 Max(Abs(v)) 的组合写法相比省掉了一整个临时数组的分配与读写。
Double(), Int32, Int32)求 [start, ends) 区间(前闭后开)的绝对值最大值。空区间返回 0。
Double())均值:SUM(v) / N。空数组会抛出 ArgumentException。
Single())均值:SUM(v) / N。空数组会抛出 ArgumentException。
Double())L1 范数:SUM(|v(i)|)。空数组返回 0。
Double(), Int32, Int32)求 [start, ends) 区间(前闭后开)的 L1 范数。
Double())L2 范数(欧几里得范数):SQRT(SUM(v(i) ^ 2))。空数组返回 0。
Double())最大值所在的下标(第一个匹配项)。空数组会抛出 ArgumentException。
Double())最小值所在的下标(第一个匹配项)。空数组会抛出 ArgumentException。