C# simd 性能雷点记录
先看两段代码对比:
static public T SimdDot(T[] a, T[] b) { if (a.Length != b.Length) throw new ArgumentException("The size of two matrix is not equal."); // if (a.Length == 0) throw new ArgumentException("The length of input matrix must be greater than zero."); var result = default(T); var vcount= Vector<T>.Count; int remaining = a.Length % vcount; var idx = 0; for (int i = 0; i < a.Length - remaining; i += vcount) { var va = new Vector<T>(a, idx * vcount); var vb = new Vector<T>(b, idx * vcount); result += Vector.Dot(va, vb); idx++; } for (int i = a.Length - remaining; i < a.Length; i++) { result += a[i] * b[i]; } return result; }
static public T SimdDot(ReadOnlySpan<T> a, ReadOnlySpan<T> b) { if (a.Length != b.Length) throw new ArgumentException("The size of two matrix is not equal."); // if (a.Length == 0) throw new ArgumentException("The length of input matrix must be greater than zero."); var result = default(T); var vcount= Vector<T>.Count; int remaining = a.Length % vcount; var idx = 0; for (int i = 0; i < a.Length - remaining; i += vcount) { var va = new Vector<T>(a.Slice(idx*vcount,vcount)); var vb = new Vector<T>(b.Slice(idx*vcount,vcount)); result += Vector.Dot(va, vb); idx++; } for (int i = a.Length - remaining; i < a.Length; i++) { result += a[i] * b[i]; } return result; }
这是向量的点乘运算,下面代码的性能差于传统sisd的性能,而上面的代码略好于sisd代码,它们之间的差别在于 使用 ReadOnlySpan<T>.Slice函数,看来这是个坑点,明明它是号称性能优势的Span<T>系列啊,所以比较出乎意料。特此记上一笔。
这结果是使用上面代码(非下面有红字部分代码段)的测试结果,如果使用有标红部分代码来测试的话,其性能竟然会达到sisd的 3-5倍之巨。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?