11
11
12
12
namespace BenchmarkDotNet . Detectors . Cpu
13
13
{
14
+ // based on https://github.com/dotnet/runtime/tree/v10.0.0-rc.1.25451.107/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt
14
15
internal static class HardwareIntrinsics
15
16
{
16
17
internal static string GetVectorSize ( ) => Vector . IsHardwareAccelerated ? $ "VectorSize={ Vector < byte > . Count * 8 } " : string . Empty ;
17
18
18
19
internal static string GetShortInfo ( )
19
20
{
20
- if ( IsX86Avx512FSupported )
21
- return GetShortAvx512Representation ( ) ;
22
- if ( IsX86Avx2Supported )
23
- return "AVX2" ;
24
- else if ( IsX86AvxSupported )
25
- return "AVX" ;
26
- else if ( IsX86Sse42Supported )
27
- return "SSE4.2" ;
28
- else if ( IsX86Sse41Supported )
29
- return "SSE4.1" ;
30
- else if ( IsX86Ssse3Supported )
31
- return "SSSE3" ;
32
- else if ( IsX86Sse3Supported )
33
- return "SSE3" ;
34
- else if ( IsX86Sse2Supported )
35
- return "SSE2" ;
36
- else if ( IsX86SseSupported )
37
- return "SSE" ;
38
- else if ( IsX86BaseSupported )
39
- return "X86Base" ;
40
- else if ( IsArmAdvSimdSupported )
41
- return "AdvSIMD" ;
21
+ if ( IsX86BaseSupported )
22
+ {
23
+ if ( IsX86Avx512Supported )
24
+ {
25
+ return "x86-64-v4" ;
26
+ }
27
+ else if ( IsX86Avx2Supported )
28
+ {
29
+ return "x86-64-v3" ;
30
+ }
31
+ else if ( IsX86Sse42Supported )
32
+ {
33
+ return "x86-64-v2" ;
34
+ }
35
+ else
36
+ {
37
+ return "x86-64-v1" ;
38
+ }
39
+ }
42
40
else if ( IsArmBaseSupported )
43
- return "ArmBase" ;
41
+ {
42
+ return "armv8.0-a" ;
43
+ }
44
44
else
45
+ {
45
46
return GetVectorSize ( ) ; // Runtimes prior to .NET Core 3.0 (APIs did not exist so we print non-exact Vector info)
47
+ }
46
48
}
47
49
48
50
internal static string GetFullInfo ( Platform platform )
@@ -55,32 +57,31 @@ static IEnumerable<string> GetCurrentProcessInstructionSets(Platform platform)
55
57
{
56
58
case Platform . X86 :
57
59
case Platform . X64 :
58
-
59
- if ( IsX86Avx512FSupported ) yield return GetShortAvx512Representation ( ) ;
60
- else if ( IsX86Avx2Supported ) yield return "AVX2" ;
61
- else if ( IsX86AvxSupported ) yield return "AVX" ;
62
- else if ( IsX86Sse42Supported ) yield return "SSE4.2" ;
63
- else if ( IsX86Sse41Supported ) yield return "SSE4.1" ;
64
- else if ( IsX86Ssse3Supported ) yield return "SSSE3" ;
65
- else if ( IsX86Sse3Supported ) yield return "SSE3" ;
66
- else if ( IsX86Sse2Supported ) yield return "SSE2" ;
67
- else if ( IsX86SseSupported ) yield return "SSE" ;
68
- else if ( IsX86BaseSupported ) yield return "X86Base" ;
69
-
70
- if ( IsX86AesSupported ) yield return "AES" ;
71
- if ( IsX86Bmi1Supported ) yield return "BMI1" ;
72
- if ( IsX86Bmi2Supported ) yield return "BMI2" ;
73
- if ( IsX86FmaSupported ) yield return "FMA" ;
74
- if ( IsX86LzcntSupported ) yield return "LZCNT" ;
75
- if ( IsX86PclmulqdqSupported ) yield return "PCLMUL" ;
76
- if ( IsX86PopcntSupported ) yield return "POPCNT" ;
60
+ {
61
+ if ( IsX86Avx10v2Supported ) yield return "AVX10v2" ;
62
+ if ( IsX86Avx10v1Supported )
63
+ {
64
+ yield return "AVX10v1" ;
65
+ yield return "AVX512 BF16+FP16" ;
66
+ }
67
+ if ( IsX86Avx512v3Supported ) yield return "AVX512 BITALG+VBMI2+VNNI+VPOPCNTDQ" ;
68
+ if ( IsX86Avx512v2Supported ) yield return "AVX512 IFMA+VBMI" ;
69
+ if ( IsX86Avx512Supported ) yield return "AVX512 F+BW+CD+DQ+VL" ;
70
+ if ( IsX86Avx2Supported ) yield return "AVX2+BMI1+BMI2+F16C+FMA+LZCNT+MOVBE" ;
71
+ if ( IsX86AvxSupported ) yield return "AVX" ;
72
+ if ( IsX86Sse42Supported ) yield return "SSE3+SSSE3+SSE4.1+SSE4.2+POPCNT" ;
73
+ if ( IsX86BaseSupported ) yield return "X86Base+SSE+SSE2" ;
74
+ if ( IsX86AesSupported ) yield return "AES+PCLMUL" ;
77
75
if ( IsX86AvxVnniSupported ) yield return "AvxVnni" ;
78
76
if ( IsX86SerializeSupported ) yield return "SERIALIZE" ;
79
- // TODO: Add MOVBE when API is added.
80
77
break ;
78
+ }
81
79
case Platform . Arm64 :
82
- if ( IsArmAdvSimdSupported ) yield return "AdvSIMD" ;
83
- else if ( IsArmBaseSupported ) yield return "ArmBase" ;
80
+ {
81
+ if ( IsArmBaseSupported )
82
+ {
83
+ yield return "ArmBase+AdvSimd" ;
84
+ }
84
85
85
86
if ( IsArmAesSupported ) yield return "AES" ;
86
87
if ( IsArmCrc32Supported ) yield return "CRC32" ;
@@ -89,71 +90,39 @@ static IEnumerable<string> GetCurrentProcessInstructionSets(Platform platform)
89
90
if ( IsArmSha1Supported ) yield return "SHA1" ;
90
91
if ( IsArmSha256Supported ) yield return "SHA256" ;
91
92
break ;
93
+ }
94
+
92
95
default :
93
96
yield break ;
94
97
}
95
98
}
96
99
}
97
100
98
- private static string GetShortAvx512Representation ( )
99
- {
100
- StringBuilder avx512 = new ( "AVX-512F" ) ;
101
- if ( IsX86Avx512CDSupported ) avx512 . Append ( "+CD" ) ;
102
- if ( IsX86Avx512BWSupported ) avx512 . Append ( "+BW" ) ;
103
- if ( IsX86Avx512DQSupported ) avx512 . Append ( "+DQ" ) ;
104
- if ( IsX86Avx512FVLSupported ) avx512 . Append ( "+VL" ) ;
105
- if ( IsX86Avx512VbmiSupported ) avx512 . Append ( "+VBMI" ) ;
106
-
107
- return avx512 . ToString ( ) ;
108
- }
109
-
101
+ #pragma warning disable CA2252 // Some APIs require opting into preview features
110
102
internal static bool IsX86BaseSupported =>
111
103
#if NET6_0_OR_GREATER
112
- X86Base . IsSupported ;
113
- #elif NETSTANDARD
114
- GetIsSupported ( "System.Runtime.Intrinsics.X86.X86Base" ) ;
115
- #endif
116
-
117
- internal static bool IsX86SseSupported =>
118
- #if NET6_0_OR_GREATER
119
- Sse . IsSupported ;
120
- #elif NETSTANDARD
121
- GetIsSupported ( "System.Runtime.Intrinsics.X86.Sse" ) ;
122
- #endif
123
-
124
- internal static bool IsX86Sse2Supported =>
125
- #if NET6_0_OR_GREATER
104
+ X86Base . IsSupported &&
105
+ Sse . IsSupported &&
126
106
Sse2 . IsSupported ;
127
107
#elif NETSTANDARD
108
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.X86Base" ) &&
109
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Sse" ) &&
128
110
GetIsSupported ( "System.Runtime.Intrinsics.X86.Sse2" ) ;
129
111
#endif
130
112
131
- internal static bool IsX86Sse3Supported =>
132
- #if NET6_0_OR_GREATER
133
- Sse3 . IsSupported ;
134
- #elif NETSTANDARD
135
- GetIsSupported ( "System.Runtime.Intrinsics.X86.Sse3" ) ;
136
- #endif
137
-
138
- internal static bool IsX86Ssse3Supported =>
139
- #if NET6_0_OR_GREATER
140
- Ssse3 . IsSupported ;
141
- #elif NETSTANDARD
142
- GetIsSupported ( "System.Runtime.Intrinsics.X86.Ssse3" ) ;
143
- #endif
144
-
145
- internal static bool IsX86Sse41Supported =>
146
- #if NET6_0_OR_GREATER
147
- Sse41 . IsSupported ;
148
- #elif NETSTANDARD
149
- GetIsSupported ( "System.Runtime.Intrinsics.X86.Sse41" ) ;
150
- #endif
151
-
152
113
internal static bool IsX86Sse42Supported =>
153
114
#if NET6_0_OR_GREATER
154
- Sse42 . IsSupported ;
115
+ Sse3 . IsSupported &&
116
+ Ssse3 . IsSupported &&
117
+ Sse41 . IsSupported &&
118
+ Sse42 . IsSupported &&
119
+ Popcnt . IsSupported ;
155
120
#elif NETSTANDARD
156
- GetIsSupported ( "System.Runtime.Intrinsics.X86.Sse42" ) ;
121
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Sse3" ) &&
122
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Ssse3" ) &&
123
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Sse41" ) &&
124
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Sse42" ) &&
125
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Popcnt" ) ;
157
126
#endif
158
127
159
128
internal static bool IsX86AvxSupported =>
@@ -165,107 +134,88 @@ private static string GetShortAvx512Representation()
165
134
166
135
internal static bool IsX86Avx2Supported =>
167
136
#if NET6_0_OR_GREATER
168
- Avx2 . IsSupported ;
137
+ Avx2 . IsSupported &&
138
+ Bmi1 . IsSupported &&
139
+ Bmi2 . IsSupported &&
140
+ Fma . IsSupported &&
141
+ Lzcnt . IsSupported ;
169
142
#elif NETSTANDARD
170
- GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx2" ) ;
171
- #endif
172
-
173
- internal static bool IsX86Avx512FSupported =>
174
- #if NET8_0_OR_GREATER
175
- Avx512F . IsSupported ;
176
- #else
177
- GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx512F" ) ;
143
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx2" ) &&
144
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Bmi1" ) &&
145
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Bmi2" ) &&
146
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Fma" ) &&
147
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Lzcnt" ) ;
178
148
#endif
179
149
180
- internal static bool IsX86Avx512FVLSupported =>
150
+ internal static bool IsX86Avx512Supported =>
181
151
#if NET8_0_OR_GREATER
182
- Avx512F . VL . IsSupported ;
152
+ Avx512F . IsSupported &&
153
+ Avx512F . VL . IsSupported &&
154
+ Avx512BW . IsSupported &&
155
+ Avx512BW . VL . IsSupported &&
156
+ Avx512CD . IsSupported &&
157
+ Avx512CD . VL . IsSupported &&
158
+ Avx512DQ . IsSupported &&
159
+ Avx512DQ . VL . IsSupported ;
183
160
#else
184
- GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx512F+VL" ) ;
161
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx512F" ) &&
162
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx512F+VL" ) &&
163
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx512BW" ) &&
164
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx512BW+VL" ) &&
165
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx512CD" ) &&
166
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx512CD+VL" ) &&
167
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx512DQ" ) &&
168
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx512DQ+VL" ) ;
185
169
#endif
186
170
187
- internal static bool IsX86Avx512BWSupported =>
171
+ internal static bool IsX86Avx512v2Supported =>
188
172
#if NET8_0_OR_GREATER
189
- Avx512BW . IsSupported ;
173
+ Avx512Vbmi . IsSupported &&
174
+ Avx512Vbmi . VL . IsSupported ;
190
175
#else
191
- GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx512BW" ) ;
176
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx512Vbmi" ) &&
177
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx512Vbmi+VL" ) ;
192
178
#endif
193
179
194
- internal static bool IsX86Avx512CDSupported =>
195
- #if NET8_0_OR_GREATER
196
- Avx512CD . IsSupported ;
180
+ internal static bool IsX86Avx512v3Supported =>
181
+ #if NET10_0_OR_GREATER
182
+ Avx512Vbmi2 . IsSupported &&
183
+ Avx512Vbmi2 . VL . IsSupported ;
197
184
#else
198
- GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx512CD" ) ;
185
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx512Vbmi2" ) &&
186
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx512Vbmi2+VL" ) ;
199
187
#endif
200
188
201
- internal static bool IsX86Avx512DQSupported =>
202
- #if NET8_0_OR_GREATER
203
- Avx512DQ . IsSupported ;
189
+ internal static bool IsX86Avx10v1Supported =>
190
+ #if NET9_0_OR_GREATER
191
+ Avx10v1 . IsSupported &&
192
+ Avx10v1 . V512 . IsSupported ;
204
193
#else
205
- GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx512DQ" ) ;
194
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx10v1" ) &&
195
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx10v1+V512" ) ;
206
196
#endif
207
197
208
- internal static bool IsX86Avx512VbmiSupported =>
209
- #if NET8_0_OR_GREATER
210
- Avx512Vbmi . IsSupported ;
198
+ internal static bool IsX86Avx10v2Supported =>
199
+ #if NET10_0_OR_GREATER
200
+ Avx10v2 . IsSupported &&
201
+ Avx10v2 . V512 . IsSupported ;
211
202
#else
212
- GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx512Vbmi" ) ;
203
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx10v2" ) &&
204
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Avx10v2+V512" ) ;
213
205
#endif
214
206
215
207
internal static bool IsX86AesSupported =>
216
208
#if NET6_0_OR_GREATER
217
- System . Runtime . Intrinsics . X86 . Aes . IsSupported ;
218
- #elif NETSTANDARD
219
- GetIsSupported ( "System.Runtime.Intrinsics.X86.Aes" ) ;
220
- #endif
221
-
222
- internal static bool IsX86Bmi1Supported =>
223
- #if NET6_0_OR_GREATER
224
- Bmi1 . IsSupported ;
225
- #elif NETSTANDARD
226
- GetIsSupported ( "System.Runtime.Intrinsics.X86.Bmi1" ) ;
227
- #endif
228
-
229
- internal static bool IsX86Bmi2Supported =>
230
- #if NET6_0_OR_GREATER
231
- Bmi2 . IsSupported ;
232
- #elif NETSTANDARD
233
- GetIsSupported ( "System.Runtime.Intrinsics.X86.Bmi2" ) ;
234
- #endif
235
-
236
- internal static bool IsX86FmaSupported =>
237
- #if NET6_0_OR_GREATER
238
- Fma . IsSupported ;
239
- #elif NETSTANDARD
240
- GetIsSupported ( "System.Runtime.Intrinsics.X86.Fma" ) ;
241
- #endif
242
-
243
- internal static bool IsX86LzcntSupported =>
244
- #if NET6_0_OR_GREATER
245
- Lzcnt . IsSupported ;
246
- #elif NETSTANDARD
247
- GetIsSupported ( "System.Runtime.Intrinsics.X86.Lzcnt" ) ;
248
- #endif
249
-
250
- internal static bool IsX86PclmulqdqSupported =>
251
- #if NET6_0_OR_GREATER
209
+ System . Runtime . Intrinsics . X86 . Aes . IsSupported &&
252
210
Pclmulqdq . IsSupported ;
253
211
#elif NETSTANDARD
212
+ GetIsSupported ( "System.Runtime.Intrinsics.X86.Aes" ) &&
254
213
GetIsSupported ( "System.Runtime.Intrinsics.X86.Pclmulqdq" ) ;
255
214
#endif
256
215
257
- internal static bool IsX86PopcntSupported =>
258
- #if NET6_0_OR_GREATER
259
- Popcnt . IsSupported ;
260
- #elif NETSTANDARD
261
- GetIsSupported ( "System.Runtime.Intrinsics.X86.Popcnt" ) ;
262
- #endif
263
-
264
216
internal static bool IsX86AvxVnniSupported =>
265
217
#if NET6_0_OR_GREATER
266
- #pragma warning disable CA2252 // This API requires opting into preview features
267
218
AvxVnni . IsSupported ;
268
- #pragma warning restore CA2252 // This API requires opting into preview features
269
219
#elif NETSTANDARD
270
220
GetIsSupported ( "System.Runtime.Intrinsics.X86.AvxVnni" ) ;
271
221
#endif
@@ -279,15 +229,10 @@ private static string GetShortAvx512Representation()
279
229
280
230
internal static bool IsArmBaseSupported =>
281
231
#if NET6_0_OR_GREATER
282
- ArmBase . IsSupported ;
283
- #elif NETSTANDARD
284
- GetIsSupported ( "System.Runtime.Intrinsics.Arm.ArmBase" ) ;
285
- #endif
286
-
287
- internal static bool IsArmAdvSimdSupported =>
288
- #if NET6_0_OR_GREATER
232
+ ArmBase . IsSupported &&
289
233
AdvSimd . IsSupported ;
290
234
#elif NETSTANDARD
235
+ GetIsSupported ( "System.Runtime.Intrinsics.Arm.ArmBase" ) &&
291
236
GetIsSupported ( "System.Runtime.Intrinsics.Arm.AdvSimd" ) ;
292
237
#endif
293
238
@@ -332,6 +277,7 @@ private static string GetShortAvx512Representation()
332
277
#elif NETSTANDARD
333
278
GetIsSupported ( "System.Runtime.Intrinsics.Arm.Sha256" ) ;
334
279
#endif
280
+ #pragma warning restore CA2252 // Some APIs require opting into preview features
335
281
336
282
private static bool GetIsSupported ( [ DynamicallyAccessedMembers ( DynamicallyAccessedMemberTypes . PublicProperties ) ] string typeName )
337
283
{
0 commit comments