From 18633be1c14cb4ae717351efff1040dd954acf55 Mon Sep 17 00:00:00 2001 From: ntr Date: Sun, 20 Aug 2023 14:23:36 +0200 Subject: [PATCH 1/4] Add HardwareIntrinsics AVX-512 info --- src/BenchmarkDotNet/BenchmarkDotNet.csproj | 2 +- .../Portability/Cpu/HardwareIntrinsics.cs | 45 ++++++++++++++++++- src/BenchmarkDotNet/Portability/Libc.cs | 2 + 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/BenchmarkDotNet/BenchmarkDotNet.csproj b/src/BenchmarkDotNet/BenchmarkDotNet.csproj index 50e6733592..12eeb1651a 100644 --- a/src/BenchmarkDotNet/BenchmarkDotNet.csproj +++ b/src/BenchmarkDotNet/BenchmarkDotNet.csproj @@ -2,7 +2,7 @@ BenchmarkDotNet - netstandard2.0;net6.0 + netstandard2.0;net6.0;net8.0 true $(NoWarn);1701;1702;1705;1591;3005;NU1702;CS3001;CS3003 BenchmarkDotNet diff --git a/src/BenchmarkDotNet/Portability/Cpu/HardwareIntrinsics.cs b/src/BenchmarkDotNet/Portability/Cpu/HardwareIntrinsics.cs index 68c48809b7..dc7a7301a6 100644 --- a/src/BenchmarkDotNet/Portability/Cpu/HardwareIntrinsics.cs +++ b/src/BenchmarkDotNet/Portability/Cpu/HardwareIntrinsics.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Numerics; using BenchmarkDotNet.Environments; -using System.Diagnostics.CodeAnalysis; #if NET6_0_OR_GREATER using System.Runtime.Intrinsics.X86; using System.Runtime.Intrinsics.Arm; @@ -16,6 +16,8 @@ internal static class HardwareIntrinsics internal static string GetShortInfo() { + if (IsX86Avx512FSupported) + return "AVX-512"; if (IsX86Avx2Supported) return "AVX2"; else if (IsX86AvxSupported) @@ -52,6 +54,12 @@ static IEnumerable GetCurrentProcessInstructionSets(Platform platform) { case Platform.X86: case Platform.X64: + if (IsX86Avx512FSupported) yield return "AVX-512F"; + if (IsX86Avx512BWSupported) yield return "AVX-512BW"; + if (IsX86Avx512CDSupported) yield return "AVX-512CD"; + if (IsX86Avx512DQSupported) yield return "AVX-512DQ"; + if (IsX86Avx512VbmiSupported) yield return "AVX-512VBMI"; + if (IsX86Avx2Supported) yield return "AVX2"; else if (IsX86AvxSupported) yield return "AVX"; else if (IsX86Sse42Supported) yield return "SSE4.2"; @@ -153,6 +161,41 @@ static IEnumerable GetCurrentProcessInstructionSets(Platform platform) GetIsSupported("System.Runtime.Intrinsics.X86.Avx2"); #endif + internal static bool IsX86Avx512FSupported => +#if NET8_0_OR_GREATER + Avx512F.IsSupported; +#else + GetIsSupported("System.Runtime.Intrinsics.X86.Avx512F"); +#endif + + internal static bool IsX86Avx512BWSupported => +#if NET8_0_OR_GREATER + Avx512BW.IsSupported; +#else + GetIsSupported("System.Runtime.Intrinsics.X86.Avx512BW"); +#endif + + internal static bool IsX86Avx512CDSupported => +#if NET8_0_OR_GREATER + Avx512CD.IsSupported; +#else + GetIsSupported("System.Runtime.Intrinsics.X86.Avx512CD"); +#endif + + internal static bool IsX86Avx512DQSupported => +#if NET8_0_OR_GREATER + Avx512DQ.IsSupported; +#else + GetIsSupported("System.Runtime.Intrinsics.X86.Avx512DQ"); +#endif + + internal static bool IsX86Avx512VbmiSupported => +#if NET8_0_OR_GREATER + Avx512Vbmi.IsSupported; +#else + GetIsSupported("System.Runtime.Intrinsics.X86.Avx512Vbmi"); +#endif + internal static bool IsX86AesSupported => #if NET6_0_OR_GREATER System.Runtime.Intrinsics.X86.Aes.IsSupported; diff --git a/src/BenchmarkDotNet/Portability/Libc.cs b/src/BenchmarkDotNet/Portability/Libc.cs index c9a3cf1322..036d7b584d 100644 --- a/src/BenchmarkDotNet/Portability/Libc.cs +++ b/src/BenchmarkDotNet/Portability/Libc.cs @@ -2,7 +2,9 @@ namespace BenchmarkDotNet.Portability { +#pragma warning disable CS8981 // The type name 'libc' only contains lower-cased ascii characters. Such names may become reserved for the language. internal static class libc +#pragma warning restore CS8981 { [DllImport(nameof(libc))] internal static extern int getppid(); From b50c942cc3cfe7dc082600867d7f1dafa84c122c Mon Sep 17 00:00:00 2001 From: ntr Date: Sun, 20 Aug 2023 14:28:09 +0200 Subject: [PATCH 2/4] add to generator --- src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs index 6fb5e5421f..bdfaa85bcf 100644 --- a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs +++ b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs @@ -160,7 +160,7 @@ private string GetILCompilerPackageReference() private string GetTrimmingSettings() => rootAllApplicationAssemblies ? "" // use the defaults - // TrimMode is set in explicit way as for older versions it might have different default value + // TrimMode is set in explicit way as for older versions it might have different default value : "linklink"; private string GetInstructionSetSettings(BuildPartition buildPartition) @@ -234,6 +234,11 @@ private static IEnumerable GetCurrentProcessInstructionSets(Platform pla if (HardwareIntrinsics.IsX86Sse42Supported) yield return "sse4.2"; if (HardwareIntrinsics.IsX86AvxSupported) yield return "avx"; if (HardwareIntrinsics.IsX86Avx2Supported) yield return "avx2"; + if (HardwareIntrinsics.IsX86Avx512FSupported) yield return "avx-512f"; + if (HardwareIntrinsics.IsX86Avx512BWSupported) yield return "avx-512bw"; + if (HardwareIntrinsics.IsX86Avx512CDSupported) yield return "avx-512cd"; + if (HardwareIntrinsics.IsX86Avx512DQSupported) yield return "avx-512dq"; + if (HardwareIntrinsics.IsX86Avx512VbmiSupported) yield return "avx-512vbmi"; if (HardwareIntrinsics.IsX86AesSupported) yield return "aes"; if (HardwareIntrinsics.IsX86Bmi1Supported) yield return "bmi"; if (HardwareIntrinsics.IsX86Bmi2Supported) yield return "bmi2"; From 5f5df17cfbfdaf1579cc1f38967e81c63b668c28 Mon Sep 17 00:00:00 2001 From: ntr Date: Sun, 20 Aug 2023 14:30:05 +0200 Subject: [PATCH 3/4] fix align by slight code change --- src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs index bdfaa85bcf..c20824cf5e 100644 --- a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs +++ b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs @@ -159,8 +159,9 @@ private string GetILCompilerPackageReference() private string GetTrimmingSettings() => rootAllApplicationAssemblies - ? "" // use the defaults - // TrimMode is set in explicit way as for older versions it might have different default value + // Use the defaults + ? "" + // TrimMode is set in explicit way as for older versions it might have different default value : "linklink"; private string GetInstructionSetSettings(BuildPartition buildPartition) From c221774d197d5fc337070c8e70d41e0228a417a5 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Thu, 16 Nov 2023 13:30:03 +0100 Subject: [PATCH 4/4] address code review feedback --- .../Portability/Cpu/HardwareIntrinsics.cs | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/src/BenchmarkDotNet/Portability/Cpu/HardwareIntrinsics.cs b/src/BenchmarkDotNet/Portability/Cpu/HardwareIntrinsics.cs index dc7a7301a6..be1d40c9ec 100644 --- a/src/BenchmarkDotNet/Portability/Cpu/HardwareIntrinsics.cs +++ b/src/BenchmarkDotNet/Portability/Cpu/HardwareIntrinsics.cs @@ -3,6 +3,8 @@ using System.Diagnostics.CodeAnalysis; using System.Numerics; using BenchmarkDotNet.Environments; +using System.Text; + #if NET6_0_OR_GREATER using System.Runtime.Intrinsics.X86; using System.Runtime.Intrinsics.Arm; @@ -17,7 +19,7 @@ internal static class HardwareIntrinsics internal static string GetShortInfo() { if (IsX86Avx512FSupported) - return "AVX-512"; + return GetShortAvx512Representation(); if (IsX86Avx2Supported) return "AVX2"; else if (IsX86AvxSupported) @@ -54,13 +56,9 @@ static IEnumerable GetCurrentProcessInstructionSets(Platform platform) { case Platform.X86: case Platform.X64: - if (IsX86Avx512FSupported) yield return "AVX-512F"; - if (IsX86Avx512BWSupported) yield return "AVX-512BW"; - if (IsX86Avx512CDSupported) yield return "AVX-512CD"; - if (IsX86Avx512DQSupported) yield return "AVX-512DQ"; - if (IsX86Avx512VbmiSupported) yield return "AVX-512VBMI"; - if (IsX86Avx2Supported) yield return "AVX2"; + if (IsX86Avx512FSupported) yield return GetShortAvx512Representation(); + else if (IsX86Avx2Supported) yield return "AVX2"; else if (IsX86AvxSupported) yield return "AVX"; else if (IsX86Sse42Supported) yield return "SSE4.2"; else if (IsX86Sse41Supported) yield return "SSE4.1"; @@ -98,6 +96,18 @@ static IEnumerable GetCurrentProcessInstructionSets(Platform platform) } } + private static string GetShortAvx512Representation() + { + StringBuilder avx512 = new ("AVX-512F"); + if (IsX86Avx512CDSupported) avx512.Append("+CD"); + if (IsX86Avx512BWSupported) avx512.Append("+BW"); + if (IsX86Avx512DQSupported) avx512.Append("+DQ"); + if (IsX86Avx512FVLSupported) avx512.Append("+VL"); + if (IsX86Avx512VbmiSupported) avx512.Append("+VBMI"); + + return avx512.ToString(); + } + internal static bool IsX86BaseSupported => #if NET6_0_OR_GREATER X86Base.IsSupported; @@ -168,6 +178,13 @@ static IEnumerable GetCurrentProcessInstructionSets(Platform platform) GetIsSupported("System.Runtime.Intrinsics.X86.Avx512F"); #endif + internal static bool IsX86Avx512FVLSupported => +#if NET8_0_OR_GREATER + Avx512F.VL.IsSupported; +#else + GetIsSupported("System.Runtime.Intrinsics.X86.Avx512F+VL"); +#endif + internal static bool IsX86Avx512BWSupported => #if NET8_0_OR_GREATER Avx512BW.IsSupported; @@ -254,8 +271,12 @@ static IEnumerable GetCurrentProcessInstructionSets(Platform platform) GetIsSupported("System.Runtime.Intrinsics.X86.AvxVnni"); #endif - // X86Serialize was introduced in .NET 7.0, BDN does not target it so we need to use reflection - internal static bool IsX86SerializeSupported => GetIsSupported("System.Runtime.Intrinsics.X86.X86Serialize"); + internal static bool IsX86SerializeSupported => +#if NET7_0_OR_GREATER + X86Serialize.IsSupported; +#else + GetIsSupported("System.Runtime.Intrinsics.X86.X86Serialize"); +#endif internal static bool IsArmBaseSupported => #if NET6_0_OR_GREATER