目录
- 什么是 SIMD
- SIMD 基础 API
- System.Runtime.Intrinsics 命名空间
- 如何理解向量的大小
- 跨平台实现方式
- SIMD 指令集的使用
- System.Numerics 命名空间中的 SIMD 支持
- Vector 结构体
- Vector2、Vector3 和 Vector4 结构体
- Matrix2x2、Matrix3x2 和 Matrix4x4 结构体
- 其他 SIMD 的使用场景举例
- 总结
什么是 SIMD
SIMD(Single Instruction, Multiple Data) 译为 单指令多数据,是一种并行计算技术,允许单条指令同时对多个数据元素进行操作,从而提高计算效率。
与 SIMD 相对的是 SISD(Single Instruction, Single Data,单指令单数据),即每条指令只处理一个数据元素。
现在的大多数 CPU 都支持 SIMD 指令集,例如 Intel 的 SSE 和 AVX,ARM 的 NEON 等。
如果我们要对两组数组进行加法运算,传统方法(SISD)是逐个元素相加,而使用 SIMD 技术,可以一次性将多个元素加载到向量寄存器中,并执行单一的加法指令,从而显著提高计算效率。
下面我们通过一个简单的示例,对比传统的数组加法和使用 SIMD 优化后的数组加法在性能上的差异。例子中会对两个浮点数组进行加法运算,把结果存储在第三个数组中。
[code]using System.Runtime.Intrinsics;using BenchmarkDotNet.Attributes;using BenchmarkDotNet.Running;[MemoryDiagnoser]public class SimdBenchmark{ private float[] _arrA; private float[] _arrB; private float[] _resultArray; private readonly int _dataSize = 1_000_000; [GlobalSetup] public void Setup() { var random = new Random(); _arrA = new float[_dataSize]; _arrB = new float[_dataSize]; _resultArray = new float[_dataSize]; for (int i = 0; i < _dataSize; i++) { _arrA = (float)random.NextDouble() * 10f; _arrB = (float)random.NextDouble() * 10f; } } [Benchmark] public void NormalAdd() { for (int i = 0; i < _dataSize; i++) { _resultArray = _arrA + _arrB; } } [Benchmark] public void SimdAdd() { // 每次处理 4 个元素 int simdLength = Vector128.Count; // 4 int i = 0; // 处理可被 SIMD 整除的部分 for (; i = numElementsPerVector) { // 有符号最小值 (0x8000) 用于偏移正确比较 ushort sourceSignedMinValue = (ushort)(1 = 'a' and = 'a' and |