当前位置: 首页 > news >正文

发布 VectorTraits v1.0,它是 C# 下增强SIMD向量运算的类库

发布 VectorTraits v1.0, 它是C#下增强SIMD向量运算的类库

VectorTraits: SIMD Vector type traits methods (SIMD向量类型的特征方法).

NuGet: https://www.nuget.org/packages/VectorTraits/1.0.0

源代码: https://github.com/zyl910/VectorTraits

用途

总所周知,使用SIMD指令集,能够加速 多媒体处理(图形、图像、音频、视频…)、人工智能、科学计算 等。
然而,传统的SIMD编程存在以下痛点:

  • 难以跨平台。因为不同的CPU体系,提供了不同的SIMD指令集,例如 X86与Arm平台的SIMD指令集存在很多差异。如果程序欲移植到另一平台下,则需要查找该平台的SIMD指令集手册,重新开发一遍。
  • 位宽难以升级。即使是同一个平台,随着发展,会逐渐增加位数更宽的指令集。例如X86平台,除了已淘汰的64位MMX系列指令外,提供了了 128位SSE指令集、256位的AVX指令集,且部分高端处理器开始支持 512位的AVX-512指令集。以前用128位SSE系列指令编写的算法,若想移植到256位的AVX指令集,需要重新开发一遍,才能充分利用更宽的SIMD指令集。
  • 代码可读性差,开发门槛高。很多现代C语言编译器为SIMD指令,映射了内在函数(Intrinsic Functions),比编写汇编代码要容易了不少,且可读性提升了不少。但是由于函数名使用了一些晦涩的缩写,且C语言不支持函数名重载,以及C语言本身的复杂性,导致代码可读性与开发难度,仍有较高的门槛。

2016年的 .NET Core 1.0 新增了 Vector<T> 等向量类型,在很大程度上解决了以上痛点。

  • 容易跨平台。.NET平台的程序,是通过JIT(Just-In-Time Compiler,即时编译器)运行的。只编写一套基于向量方法的算法,且仅需编译为一套程序。随后该程序在不同平台上运行时,向量方法会被JIT编译为平台特有的SIMD指令集,从而充分的享用硬件加速。
  • 位宽能自动升级。对于Vector<T>类型,它的长度不是固定的,而是与该处理器的最长向量寄存器相同。具体来说,若CPU支持AVX指令集(严格来说是AVX2及以上),Vector<T>类型便是256位;若CPU仅支持SSE指令集(严格来说是SSE2及以上),Vector<T>类型便是128位。简单来说,在编写程序时仅使用Vector<T>类型就行,程序运行时,JIT会自动使用最宽的SIMD指令集。
  • 代码可读性较高,降低了开发门槛。.NET平台下,向量类型的方法名都是用完整英文单词所组成,并充分利用了函数名重载等 C# 语法特点,使这些方法名既简洁、又清晰。使得代码可读性有了很大的提高。

向量类型Vector<T> 虽然设计的好,但它缺少许多重要的向量函数,如 Ceiling、Sum、Shift、Shuffle 等。导致很多算法,难以用向量类型来实现。
.NET 平台版本升级时, 有时会增加若干个向量方法。例如2022年发布的 .NET 7.0,增加了ShiftRightArithmetic、Shuffle 等函数。但目前的向量方法还是较少, 例如缺少饱和处理等.
为了解决缺少向量方法的问题,.NET Core 3.0开始支持了内在函数。这能让开发者直接使用SIMD指令集,但这又面临了难以跨平台与位宽难以升级等问题。随着 .NET 平台的不断升级,会增加了更多的内在函数。例如 .NET 5.0 增加了 Arm平台的内在函数。
对于开发类库, 不能仅支持 .NET 7.0,而是需要支持多个 .NET 版本。于是你会面临繁琐的版本检查与条件处理. 而且 .NET Standard 类库的最高版本(2.1),仍是是不支持Ceiling等向量方法的,导致版本检查更加繁琐.

本库致力于解决以上麻烦, 使您能更方便的编写跨平台的SIMD算法。
特点:

  • 支持低版本的 .NET 程序(.NET Standard 1.1, .NET Core 1.0, .NET Framework 4.5, …)。能使低版本的 .NET 程序,也能使用最新的向量函数. 例如 .NET 7.0所新增的 ShiftRightArithmetic、Shuffle 等。
  • 功能强. 除了参考高版本 .NET 的向量方法外,本库还参考内在函数,提供了很多有用的向量方法。例如 YClamp, YNarrowSaturate …
  • 性能高。本库能充分利用 X86、Arm架构的内在函数对向量类型的运算进行硬件加速,且能够享受内联编译优化。且本库解决了BCL的部分向量方法(如Multiply, Shuffle等)在一些平台上没有硬件加速的问题, 因它补充了硬件加速算法.
  • 软件算法也很快。若发现向量类型的某个方法不支持硬件加速时,.NET Bcl会切换为软件算法,但它软件算法很多是含有分支语句的,性能较差。而本库的软件算法,是高度优化的无分支算法。
  • 使用方便。本库不仅支持 Vector<T>,还支持 Vector128<T>/Vector256<T> 等向量类型。工具类的类名很好记(Vectors/Vector64s/Vector128s/Vector256s),且通过同名的泛型类提供了许多常用的向量常数。
  • 为每一个特征方法, 增加了一些获取信息的的属性. e.g. _AcceleratedTypes, _FullAcceleratedTypes .

提示: 在 Visual Studio 的 Disassembly窗口可以查看运行时的汇编代码. 例如在支持 Avx指令集的机器上运行时, Vectors.ShiftLeft_Const 会被内联编译优化为使用 vpsllw 指令. 且对于常量值(1), 会被编译为指令的立即数.

Vectors.ShiftLeft_use_inline.png

例2: 使用 Vectors.ShiftLeft_ArgsVectors.ShiftLeft_Core, 能将部分运算挪到循环外去提前处理. 例如在支持 Avx指令集的机器上运行时, 会在循环外设置好 xmm1, 随后在内循环的vpsllw指令里使用了它. 且这里展示了: 内联编译优化消除了冗余的 xmm/ymm 转换.

Vectors.ShiftLeft_Core_use_inline.png

简介

本库为向量类型提供了许多重要的算术方法(如 Shift, Shuffle, NarrowSaturate)及常数, 使您能更方便的编写跨平台的SIMD运算代码。它充分利用了 X86、Arm架构的内在函数实现硬件加速,且能够享受内联编译优化。

常用类型:

  • Vectors: 为向量类型, 提供了常用工具函数, e.g. Create(T/T[]/Span/ReadOnlySpan), CreatePadding, CreateRotate, CreateByFunc, CreateByDouble … 它还为向量提供了特征方法, e.g. ShiftLeft、ShiftRightArithmetic、ShiftRightLogical、Shuffle …
  • Vectors<T>: 为向量类型, 提供了各种元素类型的常数. e.g. Serial, SerialDesc, XyzwWMask, MantissaMask, MaxValue, MinValue, NormOne, FixedOne, E, Pi, Tau, VMaxByte, VReciprocalMaxSByte …
  • Vector64s/Vector128s/Vector256s: 为固定位宽的向量(Vector64/Vector128/Vector256),提供了常用工具函数与特征方法.
  • Vector64s<T>/Vector128s<T>/Vector256s<T>: 为固定位宽的向量,提供了各种元素类型的常数.
  • Scalars: 为标量类型, 提供了各种工具函数. e.g. GetByDouble, GetFixedByDouble, GetByBits, GetBitsMask …
  • Scalars<T>: 为标量类型, 提供了许多常数. e.g. ExponentBits, MantissaBits, MantissaMask, MaxValue, MinValue, NormOne, FixedOne, E, Pi, Tau, VMaxByte, VReciprocalMaxSByte …
  • VectorTextUtil: 提供了一些向量的文本性工具函数. e.g. GetHex, Format, WriteLine …

特征方法:

  • 支持 .NET Standard 2.1 新增的向量方法: ConvertToDouble, ConvertToInt32, ConvertToInt64, ConvertToSingle, ConvertToUInt32, ConvertToUInt64, Narrow, Widen .
  • 支持 .NET 5.0 新增的向量方法: Ceiling, Floor .
  • 支持 .NET 6.0 新增的向量方法: Sum .
  • 支持 .NET 7.0 新增的向量方法: ExtractMostSignificantBits, Shuffle, ShiftLeft, ShiftRightArithmetic, ShiftRightLogical .
  • 提供缩窄饱和的向量方法: YNarrowSaturate, YNarrowSaturateUnsigned .
  • 提供舍入的向量方法: YRoundToEven, YRoundToZero .
  • 提供换位的向量方法: YShuffleInsert, YShuffleKernel, YShuffleG2, YShuffleG4, YShuffleG4X2 . 且提供了 ShuffleControlG2/ShuffleControlG4 enum.
  • 完整列表: TraitsMethodList

支持的指令集:

  • x86
    • 256位向量: Avx, Avx2 .
  • Arm
    • 128位向量: AdvSimd .

入门指南

1) 通过NuGet安装

可在’包管理器控制台’里输入以下命令, 或是使用’包管理器’GUI来安装本库.

NuGet: PM> Install-Package VectorTraits

2) 用法示例

静态类 Vectors 提供了许多方法, 例如 CreateRotate, ShiftLeft, Shuffle.
泛型结构体 Vectors<T> 为常用常数提供了字段.

范例代码在 samples/VectorTraits.Sample 文件夹. 源代码如下.

using System;
using System.IO;
using System.Numerics;
#if NETCOREAPP3_0_OR_GREATER
using System.Runtime.Intrinsics;
#endif
using Zyl.VectorTraits;namespace Zyl.VectorTraits.Sample {class Program {private static readonly TextWriter writer = Console.Out;static void Main(string[] args) {writer.WriteLine("VectorTraits.Sample");writer.WriteLine();VectorTraitsGlobal.Init(); // Initialization (初始化).TraitsOutput.OutputEnvironment(writer); // Output environment info. It depends on `VectorTraits.InfoInc`. This row can be deleted when only VectorTraits are used (输出环境信息. 它依赖 `VectorTraits.InfoInc`. 当仅使用 VectorTraits 时, 可以删除本行).writer.WriteLine();// -- Start --Vector<short> src = Vectors.CreateRotate<short>(0, 1, 2, 3, 4, 5, 6, 7); // The `Vectors` class provides some methods. For example, 'CreateRotate' is rotate fill (`Vectors` 类提供了许多方法. 例如 `CreateRotate` 是旋转填充).VectorTextUtil.WriteLine(writer, "src:\t{0}", src); // It can not only format the string, but also display the hexadecimal of each element in the vector on the right Easy to view vector data (它不仅能格式化字符串, 且会在右侧显示向量中各元素的十六进制. 便于查看向量数据).// ShiftLeft. It is a new vector method in `.NET 7.0` (左移位. 它是 `.NET 7.0` 新增的向量方法)const int shiftAmount = 1;Vector<short> shifted = Vectors.ShiftLeft(src, shiftAmount); // shifted[i] = src[i] << shiftAmount.VectorTextUtil.WriteLine(writer, "ShiftLeft:\t{0}", shifted);
#if NET7_0_OR_GREATER// Compare BCL function (与BCL的函数做对比).Vector<short> shiftedBCL = Vector.ShiftLeft(src, shiftAmount);VectorTextUtil.WriteLine(writer, "Equals to BCL ShiftLeft:\t{0}", shifted.Equals(shiftedBCL));
#endif// ShiftLeft_ConstVectorTextUtil.WriteLine(writer, "Equals to ShiftLeft_Const:\t{0}", shifted.Equals(Vectors.ShiftLeft_Const(src, shiftAmount))); // If the parameter shiftAmount is a constant, you can also use the Vectors' ShiftLeft_Const method. It is faster in many scenarios (若参数 shiftAmount 是常数, 还可以使用 Vectors 的 ShiftLeft_Const 方法. 它在不少场景下更快).writer.WriteLine();// Shuffle. It is a new vector method in `.NET 7.0` (换位. 它是 `.NET 7.0` 新增的向量方法)Vector<short> desc = Vectors<short>.SerialDesc; // The generic structure 'Vectors<T>' provides fields for commonly used constants. For example, 'SerialDesc' is a descending order value (泛型结构体 `Vectors<T>` 为常用常数提供了字段. 例如 `SerialDesc` 是降序的顺序值).VectorTextUtil.WriteLine(writer, "desc:\t{0}", desc);Vector<short> dst = Vectors.Shuffle(shifted, desc); // dst[i] = shifted[desc[i]].VectorTextUtil.WriteLine(writer, "Shuffle:\t{0}", dst);
#if NET7_0_OR_GREATER// Compare BCL function (与BCL的函数做对比). Vector<short> dstBCL = default; // Since `.NET 7.0`, the Shuffle method has been provided in Vector128/Vector256, but the Shuffle method has not yet been provided in Vector (自 `.NET 7.0` 开始, Vector128/Vector256 里提供了 Shuffle 方法, 但 Vector 里尚未提供 Shuffle 方法).if (Vector<short>.Count == Vector128<short>.Count) {dstBCL = Vector128.Shuffle(shifted.AsVector128(), desc.AsVector128()).AsVector();} else if (Vector<short>.Count == Vector256<short>.Count) {dstBCL = Vector256.Shuffle(shifted.AsVector256(), desc.AsVector256()).AsVector();}VectorTextUtil.WriteLine(writer, "Equals to BCL Shuffle:\t{0}", dst.Equals(dstBCL));
#endif// Shuffle_Args and Shuffle_CoreVectors.Shuffle_Args(desc, out var args0, out var args1); // The suffix is the `Args' method used for parameter calculation, which involves processing such as parameter transformation in advance It is suitable for external loop (后缀是 `Args` 的方法, 用于参数计算, 即提前进行参数变换等处理. 它适合放在外循环).Vector<short> dst2 = Vectors.Shuffle_Core(shifted, args0, args1); // The suffix is the `Core` method used for core calculations, which calculates based on cached parameters It is suitable for internal loop to improve performance (后缀是 `Core` 方法, 用于核心计算, 既根据已缓存的参数进行计算. 它适合放在内循环, 便于改善性能).VectorTextUtil.WriteLine(writer, "Equals to Shuffle_Core:\t{0}", dst.Equals(dst2));writer.WriteLine();// Show AcceleratedTypes.VectorTextUtil.WriteLine(writer, "ShiftLeft_AcceleratedTypes:\t{0}", Vectors.ShiftLeft_AcceleratedTypes);VectorTextUtil.WriteLine(writer, "Shuffle_AcceleratedTypes:\t{0}", Vectors.Shuffle_AcceleratedTypes);}}
}

3) 示例的运行结果

.NET7.0 on X86

程序: VectorTraits.Sample

VectorTraits.SampleIsRelease:      True
EnvironmentVariable(PROCESSOR_IDENTIFIER):      Intel64 Family 6 Model 142 Stepping 10, GenuineIntel
Environment.ProcessorCount:     8
Environment.Is64BitProcess:     True
Environment.OSVersion:  Microsoft Windows NT 10.0.19045.0
Environment.Version:    7.0.3
Stopwatch.Frequency:    10000000
RuntimeEnvironment.GetRuntimeDirectory: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\7.0.3\
RuntimeInformation.FrameworkDescription:        .NET 7.0.3
RuntimeInformation.OSArchitecture:      X64
RuntimeInformation.OSDescription:       Microsoft Windows 10.0.19045
RuntimeInformation.RuntimeIdentifier:   win10-x64
IntPtr.Size:    8
BitConverter.IsLittleEndian:    True
Vector.IsHardwareAccelerated:   True
Vector<byte>.Count:     32      # 256bit
Vector<float>.Count:    8       # 256bit
VectorTraitsGlobal.InitCheckSum:        7960959 # 0x0079797F
Vector<T>.Assembly.CodeBase:    file:///C:/Program Files/dotnet/shared/Microsoft.NETCore.App/7.0.3/System.Private.CoreLib.dll
GetTargetFrameworkDisplayName(VectorTextUtil):  .NET 7.0
GetTargetFrameworkDisplayName(TraitsOutput):    .NET 7.0
Vectors.Instance:       VectorTraits256Avx2src:    <0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7>        # (0000 0001 0002 0003 0004 0005 0006 0007 0000 0001 0002 0003 0004 0005 0006 0007)
ShiftLeft:      <0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6, 8, 10, 12, 14>  # (0000 0002 0004 0006 0008 000A 000C 000E 0000 0002 0004 0006 0008 000A 000C 000E)
Equals to BCL ShiftLeft:        True
Equals to ShiftLeft_Const:      Truedesc:   <15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0>  # (000F 000E 000D 000C 000B 000A 0009 0008 0007 0006 0005 0004 0003 0002 0001 0000)
Shuffle:        <14, 12, 10, 8, 6, 4, 2, 0, 14, 12, 10, 8, 6, 4, 2, 0>  # (000E 000C 000A 0008 0006 0004 0002 0000 000E 000C 000A 0008 0006 0004 0002 0000)
Equals to BCL Shuffle:  True
Equals to Shuffle_Core: TrueShiftLeft_AcceleratedTypes:     SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64        # (00001FE0)
Shuffle_AcceleratedTypes:       SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double        # (00007FE0)

注: Vectors.Instance 及之前的文本, 是TraitsOutput.OutputEnvironment输出的环境信息. 而从 src 开始的, 才是示例的主体代码.
由于CPU支持X86的Avx2指令集, 于是 Vector<byte>.Count 为 32(256bit), Vectors.InstanceVectorTraits256Avx2.

.NET7.0 on Arm

程序: VectorTraits.Sample

VectorTraits.SampleIsRelease:	True
EnvironmentVariable(PROCESSOR_IDENTIFIER):	
Environment.ProcessorCount:	2
Environment.Is64BitProcess:	True
Environment.OSVersion:	Unix 5.19.0.1025
Environment.Version:	7.0.8
Stopwatch.Frequency:	1000000000
RuntimeEnvironment.GetRuntimeDirectory:	/home/ubuntu/.dotnet/shared/Microsoft.NETCore.App/7.0.8/
RuntimeInformation.FrameworkDescription:	.NET 7.0.8
RuntimeInformation.OSArchitecture:	Arm64
RuntimeInformation.OSDescription:	Linux 5.19.0-1025-aws #26~22.04.1-Ubuntu SMP Mon Apr 24 01:58:03 UTC 2023
RuntimeInformation.RuntimeIdentifier:	ubuntu.22.04-arm64
IntPtr.Size:	8
BitConverter.IsLittleEndian:	True
Vector.IsHardwareAccelerated:	True
Vector<byte>.Count:	16	# 128bit
Vector<float>.Count:	4	# 128bit
VectorTraitsGlobal.InitCheckSum:	7960961	# 0x00797981
Vector<T>.Assembly.CodeBase:	file:///home/ubuntu/.dotnet/shared/Microsoft.NETCore.App/7.0.8/System.Private.CoreLib.dll
GetTargetFrameworkDisplayName(VectorTextUtil):	.NET 7.0
GetTargetFrameworkDisplayName(TraitsOutput):	.NET 7.0
Vectors.Instance:	VectorTraits128AdvSimdB64src:	<0, 1, 2, 3, 4, 5, 6, 7>	# (0000 0001 0002 0003 0004 0005 0006 0007)
ShiftLeft:	<0, 2, 4, 6, 8, 10, 12, 14>	# (0000 0002 0004 0006 0008 000A 000C 000E)
Equals to BCL ShiftLeft:	True
Equals to ShiftLeft_Const:	Truedesc:	<7, 6, 5, 4, 3, 2, 1, 0>	# (0007 0006 0005 0004 0003 0002 0001 0000)
Shuffle:	<14, 12, 10, 8, 6, 4, 2, 0>	# (000E 000C 000A 0008 0006 0004 0002 0000)
Equals to BCL Shuffle:	True
Equals to Shuffle_Core:	TrueShiftLeft_AcceleratedTypes:	SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64	# (00001FE0)
Shuffle_AcceleratedTypes:	SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double	# (00007FE0)

运算结果与X86的相同,只是环境信息不同。
由于CPU支持Arm的AdvSimd指令集, 于是 Vector<byte>.Count 为 16(128bit), Vectors.InstanceVectorTraits128AdvSimdB64.

.NET Framework 4.5 on X86

程序: VectorTraits.Sample.NetFw.

VectorTraits.SampleIsRelease:      True
EnvironmentVariable(PROCESSOR_IDENTIFIER):      Intel64 Family 6 Model 142 Stepping 10, GenuineIntel
Environment.ProcessorCount:     8
Environment.Is64BitProcess:     True
Environment.OSVersion:  Microsoft Windows NT 6.2.9200.0
Environment.Version:    4.0.30319.42000
Stopwatch.Frequency:    10000000
RuntimeEnvironment.GetRuntimeDirectory: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\
RuntimeInformation.FrameworkDescription:        .NET Framework 4.8.9167.0
RuntimeInformation.OSArchitecture:      X64
RuntimeInformation.OSDescription:       Microsoft Windows 10.0.19045
IntPtr.Size:    8
BitConverter.IsLittleEndian:    True
Vector.IsHardwareAccelerated:   True
Vector<byte>.Count:     32      # 256bit
Vector<float>.Count:    8       # 256bit
VectorTraitsGlobal.InitCheckSum:        -25396097       # 0xFE7C7C7F
Vector<T>.Assembly.CodeBase:    file:///E:/zylSelf/Code/cs/base/VectorTraits/samples/VectorTraits.Sample.NetFw/bin/Release/System.Numerics.Vectors.DLL
GetTargetFrameworkDisplayName(VectorTextUtil):  .NET Standard 1.1
GetTargetFrameworkDisplayName(TraitsOutput):    .NET Framework 4.5
Vectors.Instance:       VectorTraits256Basesrc:    <0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7>        # (0000 0001 0002 0003 0004 0005 0006 0007 0000 0001 0002 0003 0004 0005 0006 0007)
ShiftLeft:      <0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6, 8, 10, 12, 14>  # (0000 0002 0004 0006 0008 000A 000C 000E 0000 0002 0004 0006 0008 000A 000C 000E)
Equals to ShiftLeft_Const:      Truedesc:   <15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0>  # (000F 000E 000D 000C 000B 000A 0009 0008 0007 0006 0005 0004 0003 0002 0001 0000)
Shuffle:        <14, 12, 10, 8, 6, 4, 2, 0, 14, 12, 10, 8, 6, 4, 2, 0>  # (000E 000C 000A 0008 0006 0004 0002 0000 000E 000C 000A 0008 0006 0004 0002 0000)
Equals to Shuffle_Core: TrueShiftLeft_AcceleratedTypes:     SByte, Byte, Int16, UInt16, Int32, UInt32       # (000007E0)
Shuffle_AcceleratedTypes:       None    # (00000000)

Vectors 的 ShiftLeft/Shuffle 都能正常工作.
由于CPU支持X86的Avx2指令集, 于是 Vector<byte>.Count 为 32(256bit). Vectors.InstanceVectorTraits256Base. 它不是 VectorTraits256Avx2, 是因为直到 .NET Core 3.0 才支持内在函数.
ShiftLeft_AcceleratedTypes的值含有“Int16”等类型,这表示ShiftLeft在使用这些类型时, 是存在硬件加速的. 本库巧妙的利用了向量算法, 即使在没有内在函数时,也尽量实现了硬件加速.

基准测试结果

数据的单位: 百万次操作/秒. 数字越大, 性能越好.

ShiftLeft

ShiftLeft: 将向量的每个元素左移指定量.
它是.NET 7.0所新增的向量方法.

ShiftLeft - x86 - lntel Core i5-8250U

TypeMethod.NET Framework.NET Core 2.1.NET Core 3.1.NET 5.0.NET 6.0.NET 7.0
ByteSumSLLScalar853.802817.5281104.9931118.3811374.2551480.225
ByteSumSLLNetBcl1128.290
ByteSumSLLNetBcl_Const1137.564
ByteSumSLLTraits8296.6828114.08521811.57319960.73221044.19223074.627
ByteSumSLLTraits_Core33328.33335503.28541644.14635703.81636615.13832872.874
ByteSumSLLConstTraits10849.89910168.75425029.29029761.73733785.50232862.094
ByteSumSLLConstTraits_Core36537.66831837.58639307.52335698.90935679.74433994.997
Int16SumSLLScalar823.668806.3951176.1331183.9661379.4981486.900
Int16SumSLLNetBcl18445.571
Int16SumSLLNetBcl_Const19054.243
Int16SumSLLTraits5076.0365047.45316986.36116653.32916496.18216114.543
Int16SumSLLTraits_Core20318.98418959.03320182.65517683.71718500.30218439.182
Int16SumSLLConstTraits5899.2565693.08416944.67319378.43421059.68219572.551
Int16SumSLLConstTraits_Core20172.95219339.31118407.67319850.71121232.27918136.492
Int32SumSLLScalar803.506820.6391307.6141328.7032199.6851587.071
Int32SumSLLNetBcl9469.894
Int32SumSLLNetBcl_Const10657.900
Int32SumSLLTraits2571.4562678.8668246.4027799.7488221.3829594.126
Int32SumSLLTraits_Core8574.3618465.71210320.83310408.38110626.91010035.217
Int32SumSLLConstTraits1493.5902922.1038155.0469293.14810579.40010185.431
Int32SumSLLConstTraits_Core8467.9748554.9209784.69910384.7329790.89810329.112
Int64SumSLLScalar797.703816.5041295.0091305.6112043.5271535.809
Int64SumSLLNetBcl4143.077
Int64SumSLLNetBcl_Const4903.130
Int64SumSLLTraits426.950458.5173867.1363941.9993964.7623713.754
Int64SumSLLTraits_Core441.378463.5374802.9114813.0184776.1824653.104
Int64SumSLLConstTraits490.135536.9493929.1094018.0724725.2934712.366
Int64SumSLLConstTraits_Core491.263531.9464930.0994737.4624782.4304371.649

说明:

  • SumSLLScalar: 使用标量算法.
  • SumSLLNetBcl: 使用BCL的方法(Vector.ShiftLeft), 参数是变量. 注意 .NET 7.0 才提供该方法.
  • SumSLLNetBcl_Const: 使用BCL的方法(Vector.ShiftLeft), 参数是常量. 注意 .NET 7.0 才提供该方法.
  • SumSLLTraits: 使用本库的普通方法(Vectors.ShiftLeft), 参数是变量.
  • SumSLLTraits_Core: 使用本库的 Core 后缀的方法(Vectors.ShiftLeft_Args, Vectors.ShiftLeft_Core), 参数是变量.
  • SumSLLConstTraits: 使用本库的 Const 后缀的方法(Vectors.ShiftLeft_Const), 参数是常量.
  • SumSLLConstTraits_Core: 使用本库的 ConstCore 后缀的方法(Vectors.ShiftLeft_Args, Vectors.ShiftLeft_ConstCore), 参数是常量.

BCL的方法(Vector.ShiftLeft) 在X86平台运行时, 仅 Int16/Int32/Int64 有硬件加速, 而 Byte 没有硬件加速. 这是可能是因为 Avx2 指令集仅有 16~64位 的左移位指令, 未提供其他类型的指令, BCL便转为软件算法了.
而本库对于这些数字类型, 会换成由其他指令组合实现的高效算法. 例如对于 Byte类型, SumSLLConstTraits_Core 在.NET 7.0的值为“32872.874”, 性能是 标量算法的 32872.874/1480.225≈22.2080 倍, 且是BCL方法的 32872.874/1137.564≈28.8976 倍.
因为X86的内在函数是从.NET Core 3.0开始才提供的. 故对于 Int64类型, 在 .NET Core 3.0 之后才有硬件加速.

对于ShiftLeft来说, 当参数shiftAmount 是常量时, 性能一般会比用变量时更高. 无论是 BCL还是本库的方法, 都是如此.
使用本库的 Core 后缀的方法, 能将部分运算挪到循环外去提前处理, 从而优化了性能. 而当 CPU提供了常数参数的指令时(专业术语是“立即数参数”), 该指令的性能一般会更高. 于是本库还提供了 ConstCore 后缀的方法, 会选择该平台最快的指令.
因“CPU睿频”、“其他进程抢占CPU资源”等因素, 有时性能波动比较大. 但请放心, 已经检查过了Release的程序运行时的汇编指令, 它已经是按最佳硬件指令运行的. 例如下图.

Vectors.ShiftLeft_Core_use_inline.png

ShiftLeft - Arm - AWS Arm t4g.small

TypeMethod.NET Core 3.1.NET 5.0.NET 6.0.NET 7.0
ByteSumSLLScalar610.192610.563653.197891.088
ByteSumSLLNetBcl19580.464
ByteSumSLLNetBcl_Const19599.073
ByteSumSLLTraits5668.03613252.89113253.57513241.598
ByteSumSLLTraits_Core14341.89515888.31515887.52019595.005
ByteSumSLLConstTraits9946.66313243.30415895.67219466.408
ByteSumSLLConstTraits_Core13201.65715896.74815894.09319447.318
Int16SumSLLScalar606.942607.226607.742765.154
Int16SumSLLNetBcl9332.186
Int16SumSLLNetBcl_Const9240.256
Int16SumSLLTraits4231.3106553.0726603.4319351.061
Int16SumSLLTraits_Core7881.8347897.8788449.5029356.142
Int16SumSLLConstTraits6577.8296620.0788444.3049359.246
Int16SumSLLConstTraits_Core8383.1077923.1198443.8029317.663
Int32SumSLLScalar749.491746.414747.2731403.533
Int32SumSLLNetBcl4537.804
Int32SumSLLNetBcl_Const4533.257
Int32SumSLLTraits3233.2143531.4413530.3894545.497
Int32SumSLLTraits_Core3901.9754140.1714142.3774505.555
Int32SumSLLConstTraits3510.4713865.2854134.1084568.054
Int32SumSLLConstTraits_Core3905.8293895.8983896.7194547.294
Int64SumSLLScalar743.187742.685743.7601372.299
Int64SumSLLNetBcl2473.172
Int64SumSLLNetBcl_Const2468.456
Int64SumSLLTraits482.0561637.2321640.5471981.831
Int64SumSLLTraits_Core488.0721970.1522088.7932468.202
Int64SumSLLConstTraits467.9421958.4322099.0952460.619
Int64SumSLLConstTraits_Core470.1121971.8982097.6932465.419

说明:

  • SumSLLScalar: 使用标量算法.
  • SumSLLNetBcl: 使用BCL的方法(Vector.ShiftLeft), 参数是变量. 注意 .NET 7.0 才提供该方法.
  • SumSLLNetBcl_Const: 使用BCL的方法(Vector.ShiftLeft), 参数是常量. 注意 .NET 7.0 才提供该方法.
  • SumSLLTraits: 使用本库的普通方法(Vectors.ShiftLeft), 参数是变量.
  • SumSLLTraits_Core: 使用本库的 Core 后缀的方法(Vectors.ShiftLeft_Args, Vectors.ShiftLeft_Core), 参数是变量.
  • SumSLLConstTraits: 使用本库的 Const 后缀的方法(Vectors.ShiftLeft_Const), 参数是常量.
  • SumSLLConstTraits_Core: 使用本库的 ConstCore 后缀的方法(Vectors.ShiftLeft_Args, Vectors.ShiftLeft_ConstCore), 参数是常量.

BCL的方法(Vector.ShiftLeft) 在Arm平台运行时, 整数类型都有硬件加速. 对于8~64位整数的左移位, AdvSimd指令集都提供了专用指令.
本库在Arm平台运行时, 也使用了同样的指令. 于是性能接近.
因为从 .NET 5.0开始, 才提供了 Arm的内在函数. 故对于 Int64类型, 在 .NET 5.0 之后才有硬件加速.

ShiftRightArithmetic

ShiftRightArithmetic: 将向量的每个有符号元素算术右移指定量.
它是.NET 7.0所新增的向量方法.

ShiftRightArithmetic - x86 - lntel Core i5-8250U

TypeMethod.NET Framework.NET Core 2.1.NET Core 3.1.NET 5.0.NET 6.0.NET 7.0
Int16SumSRAScalar823.804827.7341180.9331182.3071341.1711592.939
Int16SumSRANetBcl18480.038
Int16SumSRANetBcl_Const21052.686
Int16SumSRATraits1557.1321559.67417325.18417699.94416372.79917193.661
Int16SumSRATraits_Core1653.8161653.71418414.63219664.14717938.06818476.248
Int16SumSRAConstTraits1672.2581675.04417658.70320409.88920233.73820835.294
Int16SumSRAConstTraits_Core1714.5821667.09020076.04320212.77420994.71721053.837
Int32SumSRAScalar825.056829.7891275.7991342.3491621.2951620.315
Int32SumSRANetBcl10132.774
Int32SumSRANetBcl_Const11033.258
Int32SumSRATraits764.013759.5888195.4708298.4048314.9219937.082
Int32SumSRATraits_Core826.612825.85410576.36710449.5359783.71611108.074
Int32SumSRAConstTraits837.650834.1268484.9599238.0899979.23610053.944
Int32SumSRAConstTraits_Core856.397859.42610201.12510314.33411009.38410772.948
Int64SumSRAScalar815.238811.6451300.0521280.9821322.4411602.916
Int64SumSRANetBcl578.499
Int64SumSRANetBcl_Const553.963
Int64SumSRATraits447.196441.6903032.9032830.9352988.1302922.851
Int64SumSRATraits_Core459.781458.2693639.0923352.2553336.9743488.018
Int64SumSRAConstTraits491.449491.4203074.9262820.8643365.6423397.660
Int64SumSRAConstTraits_Core496.174491.0223660.3803365.2103398.6573237.150
SByteSumSRAScalar827.231823.6431101.5181105.2441348.3401619.984
SByteSumSRANetBcl1161.428
SByteSumSRANetBcl_Const1156.552
SByteSumSRATraits3108.5693100.70317944.55517103.39917926.97520115.939
SByteSumSRATraits_Core3298.4913288.74230742.09530212.46929604.49833040.654
SByteSumSRAConstTraits3320.8133327.91018297.66925989.44628437.42531118.235
SByteSumSRAConstTraits_Core3423.8683427.68129454.03227559.31630075.33830565.076

说明:

  • SumSRAScalar: 使用标量算法.
  • SumSRANetBcl: 使用BCL的方法(Vector.ShiftRightArithmetic), 参数是变量. 注意 .NET 7.0 才提供该方法.
  • SumSRANetBcl_Const: 使用BCL的方法(Vector.ShiftRightArithmetic), 参数是常量. 注意 .NET 7.0 才提供该方法.
  • SumSRATraits: 使用本库的普通方法(Vectors.ShiftRightArithmetic), 参数是变量.
  • SumSRATraits_Core: 使用本库的 Core 后缀的方法(Vectors.ShiftRightArithmetic_Args, Vectors.ShiftRightArithmetic_Core), 参数是变量.
  • SumSRAConstTraits: 使用本库的 Const 后缀的方法(Vectors.ShiftRightArithmetic_Const), 参数是常量.
  • SumSRAConstTraits_Core: 使用本库的 ConstCore 后缀的方法(Vectors.ShiftRightArithmetic_Args, Vectors.ShiftRightArithmetic_ConstCore), 参数是常量.

BCL的方法(Vector.ShiftRightArithmetic) 在X86平台运行时, 仅 Int16/Int32 有硬件加速, 而 SByte/Int64 没有硬件加速. 这是可能是因为 Avx2 指令集仅有 16~32位 的算术右移位指令.
而本库对于这些数字类型, 会换成由其他指令组合实现的高效算法. 从 .NET Core 3.0 开始, 具有硬件加速.

ShiftRightArithmetic - Arm - AWS Arm t4g.small

TypeMethod.NET Core 3.1.NET 5.0.NET 6.0.NET 7.0
Int16SumSRAScalar587.279541.166607.230822.580
Int16SumSRANetBcl9941.333
Int16SumSRANetBcl_Const9938.477
Int16SumSRATraits1559.1384950.4805645.4979938.217
Int16SumSRATraits_Core1823.5098388.9567904.3669938.584
Int16SumSRAConstTraits1808.9656589.8817892.4079871.343
Int16SumSRAConstTraits_Core1810.5278392.9437896.2209925.543
Int32SumSRAScalar712.668746.666747.0551188.551
Int32SumSRANetBcl4861.897
Int32SumSRANetBcl_Const4859.816
Int32SumSRATraits779.7872944.1692945.0264868.865
Int32SumSRATraits_Core914.3464125.7484135.3534862.075
Int32SumSRAConstTraits884.9143266.2723892.0164841.364
Int32SumSRAConstTraits_Core920.3894134.1643893.0884844.364
Int64SumSRAScalar717.640742.361742.3371189.925
Int64SumSRANetBcl2468.196
Int64SumSRANetBcl_Const2471.434
Int64SumSRATraits451.9561235.4291233.8181420.116
Int64SumSRATraits_Core435.1801972.7341966.9922465.932
Int64SumSRAConstTraits437.7991962.0841966.9462470.825
Int64SumSRAConstTraits_Core436.4192099.3032097.2962469.149
SByteSumSRAScalar577.766610.669672.786925.515
SByteSumSRANetBcl19792.701
SByteSumSRANetBcl_Const19792.641
SByteSumSRATraits2991.22811281.22911275.75811356.994
SByteSumSRATraits_Core3529.32616818.29716827.84419798.924
SByteSumSRAConstTraits3476.13815680.87316829.92019774.470
SByteSumSRAConstTraits_Core3577.92716813.20215762.24319759.552

说明:

  • SumSRAScalar: 使用标量算法.
  • SumSRANetBcl: 使用BCL的方法(Vector.ShiftRightArithmetic), 参数是变量. 注意 .NET 7.0 才提供该方法.
  • SumSRANetBcl_Const: 使用BCL的方法(Vector.ShiftRightArithmetic), 参数是常量. 注意 .NET 7.0 才提供该方法.
  • SumSRATraits: 使用本库的普通方法(Vectors.ShiftRightArithmetic), 参数是变量.
  • SumSRATraits_Core: 使用本库的 Core 后缀的方法(Vectors.ShiftRightArithmetic_Args, Vectors.ShiftRightArithmetic_Core), 参数是变量.
  • SumSRAConstTraits: 使用本库的 Const 后缀的方法(Vectors.ShiftRightArithmetic_Const), 参数是常量.
  • SumSRAConstTraits_Core: 使用本库的 ConstCore 后缀的方法(Vectors.ShiftRightArithmetic_Args, Vectors.ShiftRightArithmetic_ConstCore), 参数是常量.

BCL的方法(Vector.ShiftRightArithmetic) 在Arm平台运行时, 整数类型都有硬件加速. 对于8~64位整数的算术右移位, AdvSimd指令集都提供了专用指令.
本库在Arm平台运行时, 也使用了同样的指令. 于是性能接近. 从 .NET 5.0 开始, 具有硬件加速.

Shuffle

Shuffle: 换位并清零. 通过使用一组索引从输入向量中选择值,来创建一个新向量.
它是.NET 7.0所新增的向量方法. 自 .NET 7.0 开始, Vector128/Vector256 里提供了 Shuffle 方法, 但 Vector 里尚未提供 Shuffle 方法.

Shuffle 允许索引超过有效范围, 此次会将对应元素置0. 这个特性会稍微拖慢性能, 于是本库还提供了 YShuffleKernel 方法(仅换位). 若能确保索引总是在有效范围内, 用 YShuffleKernel 更快.

Shuffle - x86 - lntel Core i5-8250U

TypeMethod.NET Framework.NET Core 2.1.NET Core 3.1.NET 5.0.NET 6.0.NET 7.0
Int16SumScalar1009.1321007.748992.2991004.3701034.912989.043
Int16Sum256_Bcl775.841
Int16SumTraits1012.6261008.9006025.6298058.0758017.2789060.106
Int16SumTraits_Args01008.925988.64614845.37014590.24614413.19314209.436
Int16SumTraits_Args1008.981991.79014644.21914527.03514198.71814024.591
Int16SumKernelTraits1011.5281009.2897566.2669381.2279585.57310330.592
Int16SumKernelTraits_Args01006.331989.48815045.75314575.46014464.14714484.413
Int16SumKernelTraits_Args1017.264990.16114900.55313672.16714556.62714280.139
Int32SumScalar723.019725.013704.809708.372735.378747.651
Int32Sum256_Bcl611.393
Int32SumTraits716.509724.3695216.7575813.2067139.3379250.625
Int32SumTraits_Args0716.520703.6369278.5079221.3109159.6839728.639
Int32SumTraits_Args722.854709.6549010.8349164.8548992.3569828.623
Int32SumKernelTraits722.441725.2189554.7667064.7116932.1929996.960
Int32SumKernelTraits_Args0724.689706.34511017.87411092.30111134.92411279.116
Int32SumKernelTraits_Args727.981701.15511030.88610970.11610510.20811324.558
Int64SumScalar459.881457.952188.562477.806459.242462.021
Int64Sum256_Bcl515.863
Int64SumTraits459.302459.8762143.1292518.3252433.4493524.309
Int64SumTraits_Args0465.064441.5764508.7544449.0984406.9944484.512
Int64SumTraits_Args459.786408.5454466.0284214.8084293.4384270.565
Int64SumKernelTraits460.058458.8582702.1053195.8101714.7354046.124
Int64SumKernelTraits_Args0464.705438.2244820.7674705.8434042.2624882.344
Int64SumKernelTraits_Args463.218411.9054884.2775433.5584140.5294788.233
SByteSumScalar1263.2101262.732844.7491013.9241077.5131261.932
SByteSum256_Bcl930.329
SByteSumTraits1264.3931264.66713239.40817766.24216140.96424537.440
SByteSumTraits_Args01262.3681242.50331793.48731423.34431314.48834322.789
SByteSumTraits_Args1221.5421248.12131118.40031615.12031980.79433156.240
SByteSumKernelTraits1260.0971266.05619996.80623032.25023853.31429612.169
SByteSumKernelTraits_Args01260.4611245.53031084.95530974.02231913.28733643.052
SByteSumKernelTraits_Args1260.2721249.31630827.15230734.83132311.41832977.071

说明:

  • SumScalar: 使用标量算法.
  • Sum256_Bcl: 使用BCL的方法(Vector256.Shuffle).
  • SumTraits: 使用本库的普通方法(Vectors.Shuffle).
  • SumTraits_Args0: 使用本库的 Core 后缀的方法(Vectors.Shuffle_Args, Vectors.Shuffle_Core), 不使用ValueTuple, 而是用“out”关键字返回多个值.
  • SumTraits_Args: 使用本库的 Core 后缀的方法(Vectors.Shuffle_Args, Vectors.Shuffle_Core), 使用ValueTuple.
  • SumKernelTraits: 使用本库的YShuffleKernel的普通方法(Vectors.YShuffleKernel).
  • SumKernelTraits_Args0: 使用本库的YShuffleKernel的 Core 后缀的方法(Vectors.YShuffleKernel_Args, Vectors.YShuffleKernel_Core), 不使用ValueTuple, 而是用“out”关键字返回多个值.
  • SumKernelTraits_Args: 使用本库的YShuffleKernel的 Core 后缀的方法(Vectors.YShuffleKernel_Args, Vectors.YShuffleKernel_Core), 使用ValueTuple.

BCL的方法(Vector.Shuffle) 在X86平台运行时, 所有数字类型, 均没有硬件加速.
而本库对于这些数字类型, 会换成由其他指令组合实现的高效算法. 从 .NET Core 3.0 开始, 具有硬件加速.
使用本库的 Core 后缀的方法, 能将部分运算挪到循环外去提前处理, 从而优化了性能. 特别对于Shuffle方法来说, 性能提升幅度较大.
若能确保索引总是在有效范围内, 能用 YShuffleKernel 替代Shuffle. 它更快.
对于Args 后缀的方法, 除了可以用“out”关键字返回多个值外, 还可以用 ValueTuple 来接收多个值, 简化了代码. 但得注意 ValueTuple 有时会降低性能.

Shuffle - Arm - AWS Arm t4g.small

TypeMethod.NET Core 3.1.NET 5.0.NET 6.0.NET 7.0
Int16SumScalar424.835422.286423.070526.071
Int16Sum128_Bcl482.320
Int16SumTraits423.9424925.0344938.0775853.245
Int16SumTraits_Args0423.8728381.3957862.0559821.786
Int16SumTraits_Args400.7672982.7552976.1389769.321
Int16Sum128_AdvSimd3169.0363115.8593239.207
Int16SumKernelTraits424.3175644.8086565.5197904.834
Int16SumKernelTraits_Args0423.8997881.8237847.8689835.768
Int16SumKernelTraits_Args399.7722982.0132868.2869778.383
Int32SumScalar288.211281.081276.668317.268
Int32Sum128_Bcl303.702
Int32SumTraits287.9422447.8122561.5012912.918
Int32SumTraits_Args0286.6464103.0844110.5504796.704
Int32SumTraits_Args268.6131487.1801483.9944775.891
Int32SumKernelTraits287.9002805.3553237.3453909.519
Int32SumKernelTraits_Args0286.5564112.6894128.4024825.180
Int32SumKernelTraits_Args268.8581487.0211430.4004755.708
Int64SumScalar378.628188.199447.044552.523
Int64Sum128_Bcl712.025
Int64SumTraits379.6431015.8111089.6281242.552
Int64SumTraits_Args0380.1332091.9481967.7662465.800
Int64SumTraits_Args326.603743.033744.9082452.967
Int64SumKernelTraits379.6961221.9231480.1821756.478
Int64SumKernelTraits_Args0379.7882096.1242095.5362464.674
Int64SumKernelTraits_Args170.957715.532717.5492457.398
SByteSumScalar668.450650.673659.984833.921
SByteSum128_Bcl648.985
SByteSumTraits667.52713135.35616713.00919730.059
SByteSumTraits_Args0664.98815734.26415708.75819741.441
SByteSumTraits_Args625.4105723.5235948.76619692.665
SByteSumKernelTraits667.28015584.50515643.22519741.523
SByteSumKernelTraits_Args0664.91416731.94216685.53419726.599
SByteSumKernelTraits_Args625.7615723.9105950.54919685.073

说明:

  • SumScalar: 使用标量算法.
  • Sum128_Bcl: 使用BCL的方法(Vector128.Shuffle).
  • SumTraits: 使用本库的普通方法(Vectors.Shuffle).
  • SumTraits_Args0: 使用本库的 Core 后缀的方法(Vectors.Shuffle_Args, Vectors.Shuffle_Core), 不使用ValueTuple, 而是用“out”关键字返回多个值.
  • SumTraits_Args: 使用本库的 Core 后缀的方法(Vectors.Shuffle_Args, Vectors.Shuffle_Core), 使用ValueTuple.
  • SumKernelTraits: 使用本库的YShuffleKernel的普通方法(Vectors.YShuffleKernel).
  • SumKernelTraits_Args0: 使用本库的YShuffleKernel的 Core 后缀的方法(Vectors.YShuffleKernel_Args, Vectors.YShuffleKernel_Core), 不使用ValueTuple, 而是用“out”关键字返回多个值.
  • SumKernelTraits_Args: 使用本库的YShuffleKernel的 Core 后缀的方法(Vectors.YShuffleKernel_Args, Vectors.YShuffleKernel_Core), 使用ValueTuple.

BCL的方法(Vector.Shuffle) 在Arm平台运行时, 所有数字类型, 均没有硬件加速.
而本库对于这些数字类型, 会换成由其他指令组合实现的高效算法. 从 .NET 5.0 开始, 具有硬件加速.
注意在.NET 7.0之前, SumTraits_Args 有时与 SumTraits_Args0 的性能相差较大, 这是因为ValueTuple 在Arm下的性能损失较大.

YNarrowSaturate

YNarrowSaturate: 将两个 Vector 实例饱和缩窄为一个 Vector .

YNarrowSaturate - x86 - lntel Core i5-8250U

TypeMethod.NET Framework.NET Core 2.1.NET Core 3.1.NET 5.0.NET 6.0.NET 7.0
Int16SumNarrow_If209.442209.620210.928199.480211.138215.694
Int16SumNarrow_MinMax202.714215.451212.224214.893175.099219.752
Int16SumNarrowVectorBase13095.09813774.47213161.16513013.47213168.23915964.293
Int16SumNarrowVectorTraits13024.36413662.39628118.83425049.00428198.28227819.176
Int32SumNarrow_If210.834212.404213.735214.810208.985222.597
Int32SumNarrow_MinMax212.099211.786210.670205.029210.333208.573
Int32SumNarrowVectorBase6933.0366441.0626584.0007382.2546728.3197703.530
Int32SumNarrowVectorTraits6856.4566398.52512533.50514263.83512888.77113992.887
Int64SumNarrow_If195.128186.841195.864199.460193.475204.264
Int64SumNarrow_MinMax189.209178.971196.065191.231191.600203.201
Int64SumNarrowVectorBase1959.8061878.7242000.9762118.8581976.2642658.885
Int64SumNarrowVectorTraits1956.9081872.4652587.6362763.2822689.9312418.496
UInt16SumNarrow_If1066.840902.5161078.540974.7491067.7681083.124
UInt16SumNarrow_MinMax1066.895903.120901.484959.577900.228823.878
UInt16SumNarrowVectorBase16884.65817052.91415147.60217094.24317200.04319717.119
UInt16SumNarrowVectorTraits16862.58716975.92521142.03426121.17026440.90824575.123
UInt32SumNarrow_If1116.417961.764856.272901.272872.8111111.046
UInt32SumNarrow_MinMax1115.502902.014900.357877.358839.361854.364
UInt32SumNarrowVectorBase7824.6747015.9848617.5948176.9268059.9238801.283
UInt32SumNarrowVectorTraits7879.5567024.43812181.18010713.26011063.76511314.953
UInt64SumNarrow_If997.327847.431871.820875.547858.0601109.023
UInt64SumNarrow_MinMax865.4201083.4371107.6711095.561886.387735.609
UInt64SumNarrowVectorBase2015.3281971.9811833.6102446.3462636.1373336.732
UInt64SumNarrowVectorTraits2020.4051979.0782918.8283258.7963341.1843108.173

说明:

  • SumNarrow_If: 基于if语句的标量算法.
  • SumNarrow_MinMax: 基于Math类的 Min/Max 方法的标量算法.
  • SumNarrowVectorBase: 使用本库的基础方法(VectorTraitsBase.Statics.YNarrowSaturate). 它是通过组合使用BCL的向量方法来实现的, 能够利用硬件加速.
  • SumNarrowVectorTraits: 使用本库的特征方法(Vectors.YNarrowSaturate). 它是通过内在函数来实现的, 能获得更佳硬件加速.

对于 16~32位整数, 在 .NET Core 3.1 之后, SumNarrowVectorTraits的性能比SumNarrowVectorBase强很多. 这是因为 X86提供了专门的指令。
对于 64位整数(Int64/UInt64), 虽然X86没有提供对应指令. 但由于 SumNarrowVectorTraits 版代码使用了更佳的内在函数算法, 所以在很多时候它的性能仍是比SumNarrowVectorBase 更强。

YNarrowSaturate - Arm - AWS Arm t4g.small

TypeMethod.NET Core 3.1.NET 5.0.NET 6.0.NET 7.0
Int16SumNarrow_If154.717163.350157.517181.894
Int16SumNarrow_MinMax160.654161.130108.656184.712
Int16SumNarrowVectorBase6124.5165210.8806055.7217165.511
Int16SumNarrowVectorTraits6125.11313574.32913433.47115507.867
Int32SumNarrow_If163.905165.250160.416190.897
Int32SumNarrow_MinMax155.399155.059159.092195.986
Int32SumNarrowVectorBase2701.8103219.2902766.2673025.432
Int32SumNarrowVectorTraits2703.7096306.0226210.7198003.142
Int64SumNarrow_If161.985162.089160.805205.371
Int64SumNarrow_MinMax154.244153.980165.349197.005
Int64SumNarrowVectorBase716.8801189.1921156.6271229.301
Int64SumNarrowVectorTraits716.6613282.4553283.9693921.550
UInt16SumNarrow_If525.100530.550525.952608.947
UInt16SumNarrow_MinMax528.430527.506539.088609.259
UInt16SumNarrowVectorBase7945.7778739.6157945.9138916.311
UInt16SumNarrowVectorTraits7943.11514158.58614166.20713814.007
UInt32SumNarrow_If544.871540.266538.649621.107
UInt32SumNarrow_MinMax541.719536.718535.769621.414
UInt32SumNarrowVectorBase4001.5904022.5043954.7234379.473
UInt32SumNarrowVectorTraits4018.8156824.6376400.9476722.416
UInt64SumNarrow_If620.408620.900622.076828.917
UInt64SumNarrow_MinMax620.012619.806622.201828.565
UInt64SumNarrowVectorBase1291.0511863.5431869.9041816.732
UInt64SumNarrowVectorTraits1293.9973233.7263491.3693501.256

说明:

  • SumNarrow_If: 基于if语句的标量算法.
  • SumNarrow_MinMax: 基于Math类的 Min/Max 方法的标量算法.
  • SumNarrowVectorBase: 使用本库的基础方法(VectorTraitsBase.Statics.YNarrowSaturate). 它是通过组合使用BCL的向量方法来实现的, 能够利用硬件加速.
  • SumNarrowVectorTraits: 使用本库的特征方法(Vectors.YNarrowSaturate). 它是通过内在函数来实现的, 能获得更佳硬件加速.

因为从 .NET 5.0开始,提供了 Arm的内在函数. 故从 .NET 5.0 开始, SumNarrowVectorTraits的性能比SumNarrowVectorBase强很多.

更多结果

详见: BenchmarkResults

文档

  • 特征方法列表: TraitsMethodList
  • DocFX: 运行 docfx_serve.bat. 随后浏览 http://localhost:8080/ .
  • Doxygen: 运行 Doxywizard, 点击菜单栏的 File->Open. 选择 Doxyfile 文件,并点击“OK”. 点击“Run”Tab, 点击“Run doxygen”按钮. 它会在“doc_gen”文件夹生成文档.

变更日志

[2023-09-07] v1.0

  • Major: 支持 x86的Avx指令集, 以及Arm的 AdvSimd 指令集; 支持 NET 5.0-7.0 新增的向量方法; 还提供了 4元素换位(YShuffleG4)、饱和变窄(YNarrowSaturate, YNarrowSaturateUnsigned) 等原创的向量方法.
  • 为向量类型提供了一些工具方法及常数. e.g. Vectors, Vector64s, Vector128s, Vector256s, VectorTextUtil …
  • 支持 .NET Standard 2.1 新增的向量方法: ConvertToDouble, ConvertToInt32, ConvertToInt64, ConvertToSingle, ConvertToUInt32, ConvertToUInt64, Narrow, Widen .
  • 支持 .NET 5.0 新增的向量方法: Ceiling, Floor .
  • 支持 .NET 6.0 新增的向量方法: Sum .
  • 支持 .NET 7.0 新增的向量方法: ExtractMostSignificantBits, ShiftLeft, ShiftRightArithmetic, ShiftRightLogical, Shuffle .
  • 为 Vector128/Vector256 补充向量方法: Abs, Add, AndNot, BitwiseAnd, BitwiseOr, ConditionalSelect, Divide, GreaterThan, LessThan, Max, Min, Multiply, Negate, OnesComplement, Subtract, Xor .
  • 提供限制的向量方法: YClamp .
  • 提供缩窄饱和的向量方法: YNarrowSaturate, YNarrowSaturateUnsigned .
  • 提供舍入的向量方法: YRoundToEven, YRoundToZero .
  • 提供换位的向量方法: YShuffleInsert, YShuffleKernel, YShuffleG2, YShuffleG4, YShuffleG4X2 . Also provides ShuffleControlG2/ShuffleControlG4 enum.

完整列表: ChangeLog

相关文章:

发布 VectorTraits v1.0,它是 C# 下增强SIMD向量运算的类库

发布 VectorTraits v1.0, 它是C#下增强SIMD向量运算的类库 VectorTraits: SIMD Vector type traits methods (SIMD向量类型的特征方法). NuGet: https://www.nuget.org/packages/VectorTraits/1.0.0 源代码: https://github.com/zyl910/VectorTraits 用途 总所周知&#x…...

HCIA自学笔记01-冲突域

共享式网络&#xff08;用同一根同轴电缆通信&#xff09;中可能会出现信号冲突现象。 如图是一个10BASE5以太网&#xff0c;每个主机都是用同一根同轴电缆来与其它主机进行通信&#xff0c;因此&#xff0c;这里的同轴电缆又被称为共享介质&#xff0c;相应的网络被称为共享介…...

3D封装技术发展

长期以来&#xff0c;芯片制程微缩技术一直驱动着摩尔定律的延续。从1987年的1um制程到2015年的14nm制程&#xff0c;芯片制程迭代速度一直遵循摩尔定律的规律&#xff0c;即芯片上可以容纳的晶体管数目在大约每经过18个月到24个月便会增加一倍。但2015年以后&#xff0c;芯片制…...

探讨下live555用的编程设计模式

这个应该放到这里 7.live555mediaserver-第1阶段小结&#xff08;完整对象图和思维导图&#xff09; https://blog.csdn.net/yhb1206/article/details/127330771 但是想想&#xff0c;还是拿出来吧。 从这第1阶段就能发现&#xff0c;它实质用到了reactor网络编程模式。...

LeetCode 1123. Lowest Common Ancestor of Deepest Leaves【树,DFS,BFS,哈希表】1607

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…...

centroen 23版本换界面了

旧版本 新版本 没有与操作系统一起打包的ISO文件了&#xff0c;要么先安装系统&#xff0c;再安装Centreon&#xff0c;要么用pve导入OVF文件...

Postman 调用 Microsoft Graph API (InsCode AI 创作助手)

官方配置参考网址&#xff1a; https://learn.microsoft.com/zh-cn/graph/use-postman 获取 Azure AD 应用程序凭据&#xff1a; 在 Azure AD 中注册你的应用程序&#xff0c;并获取客户端ID和客户端密钥。这些凭据将允许你的应用程序与 Microsoft Graph 进行身份验证和访问权限…...

MySql 游标 触发器

游标 1.什么是游标 MySQL游标是一种数据库对象&#xff0c;它用于在数据库查询过程中迭代访问结果集中的每一行。游标可以被看作是一个指向查询结果集的指针&#xff0c;通过移动游标&#xff0c;可以按行读取和处理结果集的数据。在MySQL中&#xff0c;游标可以用于在存储过程…...

浅谈数据治理中的智能数据目录

在数字化转型的战略实施中&#xff0c;很多企业都在搭建自己的业务、数据及人工智能的中台。在同这些企业合作和交流中&#xff0c;越来越体会到数据目录是中台建设的核心和基础。为了更好地提供数据服务&#xff0c;发挥数据价值&#xff0c;用户需要先理解数据和信任数据。 企…...

算法通关村第十七关:青铜挑战-贪心其实很简单

青铜挑战-贪心其实很简单 1. 难以解释的贪心算法 贪心学习法则&#xff1a;直接做题&#xff0c;不考虑贪不贪心 贪心(贪婪)算法 是指在问题尽心求解时&#xff0c;在每一步选择中都采取最好或者最优&#xff08;最有利&#xff09;的选择&#xff0c;从而希望能够导致结果最…...

[Vue3 博物馆管理系统] 使用Vue3、Element-plus的Layout 布局构建组图文章

系列文章目录 第一章 定制上中下&#xff08;顶部菜单、底部区域、中间主区域显示&#xff09;三层结构首页 第二章 使用Vue3、Element-plus菜单组件构建菜单 第三章 使用Vue3、Element-plus走马灯组件构建轮播图 第四章 使用Vue3、Element-plus tabs组件构建选项卡功能 第五章…...

【LeetCode算法系列题解】第36~40题

CONTENTS LeetCode 36. 有效的数独&#xff08;中等&#xff09;LeetCode 37. 解数独&#xff08;困难&#xff09;LeetCode 38. 外观数列&#xff08;中等&#xff09;LeetCode 39. 组合总和&#xff08;中等&#xff09;LeetCode 40. 组合总和 II&#xff08;中等&#xff09…...

java+ssm+mysql电梯管理系统

项目介绍&#xff1a; 使用javassmmysql开发的电梯管理系统&#xff0c;系统包含管理员&#xff0c;监管员、安全员、维保员角色&#xff0c;功能如下&#xff1a; 管理员&#xff1a;系统用户管理&#xff08;监管员、安全员、维保员&#xff09;&#xff1b;系统公告&#…...

最近读书了吗?林曦老师与你分享来自暄桐课堂的读书方法

近来&#xff0c;大家有在开心读书吗&#xff1f;对于读书&#xff0c;有一个很生动的说法&#xff1a;“无事常读书&#xff0c;一日是四日。若活七十年&#xff0c;便二百八十。”读书帮助我们超越个体生命经验的限制&#xff0c;此时此地的我们&#xff0c;也可借由书本&…...

【AI理论学习】语言模型:从Word Embedding到ELMo

语言模型&#xff1a;从Word Embedding到ELMo ELMo原理Bi-LM总结参考资料 本文主要介绍一种建立在LSTM基础上的ELMo预训练模型。2013年的Word2Vec及2014年的GloVe的工作中&#xff0c;每个词对应一个vector&#xff0c;对于多义词无能为力。ELMo的工作对于此&#xff0c;提出了…...

多功能透明屏,在智能家居领域中,有哪些功能特点?显示、连接

多功能透明屏是一种新型的显示技术&#xff0c;它能够在透明的表面上显示图像和视频&#xff0c;并且具有多种功能。 这种屏幕可以应用于各种领域&#xff0c;如商业广告、智能家居、教育等&#xff0c;为用户提供更加便捷和多样化的体验。 首先&#xff0c;多功能透明屏可以…...

【List篇】ArrayList 详解(含图示说明)

Java中的ArrayList是一个动态数组&#xff0c;可以自动扩展容量以适应数据的添加和删除。它可以用来存储各种类型的数据&#xff0c;例如String&#xff0c;Integer&#xff0c;Boolean等。ArrayList实现了List接口&#xff0c;可以进行常见的List操作&#xff0c;例如添加、插…...

SSL证书只有收费的吗?有没有免费使用的?

首先明白SSL证书是什么SSL英文全称&#xff1a;英文全称: Secure Socket Layer Certificate,中文全称:安全套接字层证书。 SSL是一种由数字证书颁发机构(CA) 签发的数字证书。它用于建立安全的加密连接&#xff0c;确保通过网络传输的数据在客户端和服务器之间的安全性和完整性…...

48V轻混技术

文章目录 48V轻混技术的主要特点和优势48V轻混技术的优缺点优点&#xff1a;缺点&#xff1a; 48V轻混技术的主要特点和优势 48V轻混技术&#xff08;48V Mild Hybrid Technology&#xff09;是一种汽车动力系统技术&#xff0c;它结合了内燃机和电动机的优势&#xff0c;以提…...

机器学习基础算法--回归类型和评价分析

目录 1.数据归一化处理 2.数据标准化处理 3.Lasso回归模型 4.岭回归模型 5.评价指标计算 1.数据归一化处理 """ x的归一化的方法还是比较多的我们就选取最为基本的归一化方法 x(x-x_min)/(x_max-x_min) """ import numpy as np from sklea…...

MATLAB 软件功能简介

MATLAB 的名称源自 Matrix Laboratory,1984 年由美国 Mathworks 公司推向市场。 它是一种科学计算软件&#xff0c;专门以矩阵的形式处理数据。MATLAB 将高性能的数值计算和可 视化集成在一起&#xff0c;并提供了大量的内置函数&#xff0c;从而被广泛的应用于科学计算、控制…...

deepfm内容理解

对于CTR问题&#xff0c;被证明的最有效的提升任务表现的策略是特征组合(Feature Interaction)&#xff1b; 两个问题&#xff1a; 如何更好地学习特征组合&#xff0c;进而更加精确地描述数据的特点&#xff1b; 如何更高效的学习特征组合。 DNN局限 &#xff1a;当我们使…...

postgresql-集合运算

postgresql-集合运算 并集交集差集集合运算符的优先级 并集 create table excellent_emp( year int not null, emp_id integer not null, constraint pk_excellent_emp primary key(year,emp_id) );insert into excellent_emp values(2018,9); insert into excellent_emp value…...

[持续更新]计算机经典面试题基础篇Day2

[通用]计算机经典面试题基础篇Day2 1、单例模式是什么&#xff0c;线程安全吗 单例模式是一种设计模式&#xff0c;旨在确保一个类只有一个实例&#xff0c;并提供全局访问点。通过使用单例模式&#xff0c;可以避免多次创建相同的对象&#xff0c;节省内存资源&#xff0c;同…...

C++:类和对象(二)

本文主要介绍&#xff1a;构造函数、析构函数、拷贝构造函数、赋值运算符重载、const成员函数、取地址及const取地址操作符重载。 目录 一、类的六个默认成员函数 二、构造函数 1.概念 2.特性 三、析构函数 1.概念 2.特性 四、拷贝构造函数 1.概念 2.特征 五、赋值…...

Java“牵手”京东商品详情数据,京东商品详情API接口,京东API接口申请指南

京东平台商品详情接口是开放平台提供的一种API接口&#xff0c;通过调用API接口&#xff0c;开发者可以获取京东商品的标题、价格、库存、月销量、总销量、库存、详情描述、图片等详细信息 。 获取商品详情接口API是一种用于获取电商平台上商品详情数据的接口&#xff0c;通过…...

Fluidd摄像头公网无法正常显示修复一例

Fluidd摄像头在内网正常显示&#xff0c;公网一直无法显示&#xff0c;经过排查发现由于url加了端口号引起的&#xff0c;摄像头url中正常填写的是/webcam?actionsnapshot&#xff0c;或者/webcam?actionstream。但是由于nginx跳转机制&#xff0c;会被301跳转到/webcam/?ac…...

【C++ 学习 ⑳】- 详解二叉搜索树

目录 一、概念 二、实现 2.1 - BST.h 2.2 - test.cpp 三、应用 四、性能分析 一、概念 二叉搜索树&#xff08;BST&#xff0c;Binary Search Tree&#xff09;&#xff0c;又称二叉排序树或二叉查找树。 二叉搜索树是一棵二叉树&#xff0c;可以为空&#xff1b;如果不…...

Java中网络的基本介绍。网络通信,网络,ip地址,域名,端口,网络通信协议,TCP/IP传输过程,网络通信协议模型,TCP协议,UDP协议

- 网络通信 概念&#xff1a;网络通信是指通过计算机网络进行信息传输的过程&#xff0c;包括数据传输、语音通话、视频会议等。在网络通信中&#xff0c;数据被分成一系列的数据包&#xff0c;并通过网络传输到目的地。在数据传输过程中&#xff0c;需要确保数据的完整性、准…...

【Qt】总体把握文本编码问题

在项目开发中&#xff0c;经常会遇到文本编码问题。文本编码知识非常基础&#xff0c;但对于新手来说&#xff0c;可能需要花费较长的时间去尝试&#xff0c;才能在脑海中建立对编码的正确认知。文本编码原理并不难&#xff0c;难的是在项目实践中掌握正确处理文本编码的方法。…...

做网站包括服务器么/网络营销服务平台

一、客户端/服务端架构客户端/服务端架构 即C/S架构&#xff0c;包括&#xff1a;1、硬件C/S架构&#xff0c;2、软件C/S架构。互联网中处处都是C/S架构&#xff0c;学习socket 就是为了完成C/S架构的开发。C/S架构&#xff1a;  server端要&#xff1a;   1、力求一直提供…...

小程序开发和app开发差别/seo教学培训

B- 树 B-树又名B树&#xff0c;我们把所有的数据进行折半块查找&#xff0c;比如一共100条数据。在30和60的地方分一下&#xff0c;存放30和60的节点就是根节点。30和60就是该节点的关键字&#xff0c;100也就是分成了3份&#xff0c;这个节点自动创建三个指针。这三份就是根节…...

徐州手机网站建设公司哪家好/搜索引擎优化答案

2017 年 10 月 15 日&#xff0c;Kubernetes End User Conference (KEUC) 即将揭开神秘面纱。聚焦 Kubernetes 中国行业应用与技术落地&#xff0c;致力于为业界带来最新 Kubernetes 与容器技术和行业应用案例展示&#xff0c;本次大会邀请到了 Google、VMware、华为、IBM、网易…...

java有没有做项目的网站/营销推广有哪些公司

Commons-SCXML 是一个状态机框架&#xff0c; 首先介绍状态机相关的术语。 1、状态机相关术语 1、1状态机 是一种行为&#xff0c;他说明对象在它的生命周期中响应事件所经历的状态序列以及对那些事件的响应。 1、2状态 是指对象的生命周期中的条件或者状况。在此期间对象将…...

建设银行网站介绍/一站式网络推广服务

##JSON-RPC ---------- JSON-RPC是一个轻量级的远程调用协议&#xff0c;简单易用。 **请求数据体**: { "method": "getName", "params": ["1"], "id": 1 } method: 远端的方法名 params: 远程方法接收的参数列表 id: 本次请…...

现在做网站还用dw做模板了吗/建设网站的步骤

近期&#xff0c;爱奇艺携手华为在华为cLab创新实验室完成了基于5G MECCDN的边缘加速业务验证&#xff0c;通过实现在接近用户一端完成数据存储、计算与分析——即5G MEC的规模化落地&#xff0c;打通5G商业落地的核心技术的关键一环&#xff0c;在视频行业中抢跑5G商用落地。2…...