如何基于SIMD向量高效拆分填充多数组?(性能优化+低分配)
高性能拆分Vector256数组分量
在性能敏感场景下,需将Vector256<double>[]类型的输入数组拆分,把每个向量的X、Y、Z、W分量分别填充到独立的double[]数组X、Y、Z、W中。
已尝试的方案
- Linq:速度慢且存在额外内存分配;
- Parallel.For:速度提升一倍,但仍有额外分配,且这两种方案的额外分配无法通过内存池复用。
输入示例代码
Vector256<double>[] input = GetVectors(); double[] X, Y, Z, W; // how do I fill X, Y, Z, W with their respective values in a performant way?
基准测试代码
[Benchmark] public double[][] Linq() { var result = new double[4][]; result[0] = _array.Select(x => x.X).ToArray(); result[1] = _array.Select(x => x.Y).ToArray(); result[2] = _array.Select(x => x.Z).ToArray(); result[3] = _array.Select(x => x.W).ToArray(); return result; } [Benchmark(Baseline = true)] public double[][] ParallelFor() { var result = new double[][] { new double[Count], new double[Count], new double[Count], new double[Count] }; Parallel.For(0, Count, i => { result[0][i] = _array[i].X; result[1][i] = _array[i].Y; result[2][i] = _array[i].Z; result[3][i] = _array[i].W; }); return result; }
基准测试结果
| 方法 | Count | 均值 | 误差 | 标准差 | 比值 | 比值标准差 | Gen0 | Gen1 | Gen2 | 分配内存 | 分配比值 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Linq | 1000 | 13.259 us | 0.1522 us | 0.1271 us | 1.47 | 0.02 | 10.2997 | - | - | 31.59 KB | 0.94 |
| ParallelFor | 1000 | 8.993 us | 0.0837 us | 0.0699 us | 1.00 | 0.00 | 11.1389 | - | - | 33.58 KB | 1.00 |
| Linq | 10000 | 136.482 us | 2.7235 us | 3.8179 us | 2.94 | 0.09 | 67.3828 | 33.4473 | - | 312.84 KB | 0.99 |
| ParallelFor | 10000 | 46.989 us | 0.6139 us | 0.5742 us | 1.00 | 0.00 | 75.0732 | 36.0718 | - | 314.83 KB | 1.00 |
| Linq | 100000 | 1,877.981 us | 18.9144 us | 15.7944 us | 1.92 | 0.11 | 562.5000 | 562.5000 | 562.5000 | 3125.51 KB | 1.00 |
| ParallelFor | 100000 | 992.898 us | 19.7800 us | 50.7037 us | 1.00 | 0.00 | 260.7422 | 256.8359 | 256.8359 | 3130.72 KB | 1.00 |
优化目标
希望通过非托管内存操作或SIMD优化技术,实现更低内存分配、更高性能的拆分填充方案。
内容的提问来源于stack exchange,提问作者JustNrik
相关产品推荐
相关产品推荐

