3
3
using System . Diagnostics . CodeAnalysis ;
4
4
using System . Linq ;
5
5
using System . Text . RegularExpressions ;
6
+ using BenchmarkDotNet . Extensions ;
6
7
using BenchmarkDotNet . Helpers ;
7
8
using BenchmarkDotNet . Portability . Cpu ;
8
9
using Perfolizer . Horology ;
9
10
10
- namespace BenchmarkDotNet . Environments
11
+ namespace BenchmarkDotNet . Environments ;
12
+
13
+ public static class ProcessorBrandStringHelper
11
14
{
12
- public static class ProcessorBrandStringHelper
15
+ /// <summary>
16
+ /// Transform a processor brand string to a nice form for summary.
17
+ /// </summary>
18
+ /// <param name="cpuInfo">The CPU information</param>
19
+ /// <param name="includeMaxFrequency">Whether to include determined max frequency information</param>
20
+ /// <returns>Prettified version</returns>
21
+ public static string Prettify ( CpuInfo ? cpuInfo , bool includeMaxFrequency = false )
13
22
{
14
- /// <summary>
15
- /// Transform a processor brand string to a nice form for summary.
16
- /// </summary>
17
- /// <param name="cpuInfo">The CPU information</param>
18
- /// <param name="includeMaxFrequency">Whether to include determined max frequency information</param>
19
- /// <returns>Prettified version</returns>
20
- public static string Prettify ( CpuInfo cpuInfo , bool includeMaxFrequency = false )
21
- {
22
- if ( cpuInfo == null || string . IsNullOrEmpty ( cpuInfo . ProcessorName ) )
23
- {
24
- return "Unknown processor" ;
25
- }
23
+ string ? processorName = cpuInfo ? . ProcessorName ;
24
+ if ( processorName == null || processorName . IsBlank ( ) )
25
+ return "Unknown processor" ;
26
26
27
- // Remove parts which don't provide any useful information for user
28
- var processorName = cpuInfo . ProcessorName . Replace ( "@" , "" ) . Replace ( "(R)" , "" ) . Replace ( "(TM)" , "" ) ;
27
+ // Remove parts which don't provide any useful information for user
28
+ processorName = processorName . Replace ( "@" , "" ) . Replace ( "(R)" , "" ) . Replace ( "(TM)" , "" ) ;
29
29
30
- // If we have found physical core(s), we can safely assume we can drop extra info from brand
31
- if ( cpuInfo . PhysicalCoreCount . HasValue && cpuInfo . PhysicalCoreCount . Value > 0 )
32
- processorName = Regex . Replace ( processorName , @"(\w+?-Core Processor)" , "" ) . Trim ( ) ;
30
+ // If we have found physical core(s), we can safely assume we can drop extra info from brand
31
+ if ( cpuInfo . PhysicalCoreCount is > 0 )
32
+ processorName = Regex . Replace ( processorName , @"(\w+?-Core Processor)" , "" ) . Trim ( ) ;
33
33
34
- string frequencyString = GetBrandStyledActualFrequency ( cpuInfo . NominalFrequency ) ;
35
- if ( includeMaxFrequency && frequencyString != null && ! processorName . Contains ( frequencyString ) )
36
- {
37
- // show Max only if there's already a frequency name to differentiate the two
38
- string maxFrequency = processorName . Contains ( "Hz" ) ? $ "(Max: { frequencyString } )" : frequencyString ;
39
- processorName = $ "{ processorName } { maxFrequency } ";
40
- }
34
+ string frequencyString = GetBrandStyledNominalFrequency ( cpuInfo . NominalFrequency ) ;
35
+ if ( includeMaxFrequency && frequencyString != null && ! processorName . Contains ( frequencyString ) )
36
+ {
37
+ // show Max only if there's already a frequency name to differentiate the two
38
+ string maxFrequency = processorName . Contains ( "Hz" ) ? $ "(Max: { frequencyString } )" : frequencyString ;
39
+ processorName = $ "{ processorName } { maxFrequency } ";
40
+ }
41
41
42
- // Remove double spaces
43
- processorName = Regex . Replace ( processorName . Trim ( ) , @"\s+" , " " ) ;
42
+ // Remove double spaces
43
+ processorName = Regex . Replace ( processorName . Trim ( ) , @"\s+" , " " ) ;
44
44
45
- // Add microarchitecture name if known
46
- string microarchitecture = ParseMicroarchitecture ( processorName ) ;
47
- if ( microarchitecture != null )
48
- processorName = $ "{ processorName } ({ microarchitecture } )";
45
+ // Add microarchitecture name if known
46
+ string microarchitecture = ParseMicroarchitecture ( processorName ) ;
47
+ if ( microarchitecture != null )
48
+ processorName = $ "{ processorName } ({ microarchitecture } )";
49
49
50
- return processorName ;
51
- }
50
+ return processorName ;
51
+ }
52
52
53
- /// <summary>
54
- /// Presents actual processor's frequency into brand string format
55
- /// </summary>
56
- /// <param name="frequency"></param>
57
- private static string GetBrandStyledActualFrequency ( Frequency ? frequency )
58
- {
59
- if ( frequency == null )
60
- return null ;
61
- return $ "{ frequency . Value . ToGHz ( ) . ToString ( "N2" , DefaultCultureInfo . Instance ) } GHz";
62
- }
53
+ /// <summary>
54
+ /// Presents actual processor's frequency into brand string format
55
+ /// </summary>
56
+ /// <param name="frequency"></param>
57
+ private static string ? GetBrandStyledNominalFrequency ( Frequency ? frequency )
58
+ {
59
+ if ( frequency == null )
60
+ return null ;
61
+ return $ "{ frequency . Value . ToGHz ( ) . ToString ( "N2" , DefaultCultureInfo . Instance ) } GHz";
62
+ }
63
63
64
- /// <summary>
65
- /// Parse a processor name and tries to return a microarchitecture name.
66
- /// Works only for well-known microarchitectures.
67
- /// </summary>
68
- private static string ? ParseMicroarchitecture ( string processorName )
64
+ /// <summary>
65
+ /// Parse a processor name and tries to return a microarchitecture name.
66
+ /// Works only for well-known microarchitectures.
67
+ /// </summary>
68
+ private static string ? ParseMicroarchitecture ( string processorName )
69
+ {
70
+ if ( processorName . StartsWith ( "Intel Core" ) )
69
71
{
70
- if ( processorName . StartsWith ( "Intel Core" ) )
72
+ string model = processorName . Substring ( "Intel Core" . Length ) . Trim ( ) ;
73
+
74
+ // Core i3/5/7/9
75
+ if (
76
+ model . Length > 4 &&
77
+ model [ 0 ] == 'i' &&
78
+ ( model [ 1 ] == '3' || model [ 1 ] == '5' || model [ 1 ] == '7' || model [ 1 ] == '9' ) &&
79
+ ( model [ 2 ] == '-' || model [ 2 ] == ' ' ) )
71
80
{
72
- string model = processorName . Substring ( "Intel Core" . Length ) . Trim ( ) ;
73
-
74
- // Core i3/5/7/9
75
- if (
76
- model . Length > 4 &&
77
- model [ 0 ] == 'i' &&
78
- ( model [ 1 ] == '3' || model [ 1 ] == '5' || model [ 1 ] == '7' || model [ 1 ] == '9' ) &&
79
- ( model [ 2 ] == '-' || model [ 2 ] == ' ' ) )
80
- {
81
- string modelNumber = model . Substring ( 3 ) ;
82
- if ( modelNumber . StartsWith ( "CPU" ) )
83
- modelNumber = modelNumber . Substring ( 3 ) . Trim ( ) ;
84
- if ( modelNumber . Contains ( "CPU" ) )
85
- modelNumber = modelNumber . Substring ( 0 , modelNumber . IndexOf ( "CPU" , StringComparison . Ordinal ) ) . Trim ( ) ;
86
- return ParseIntelCoreMicroarchitecture ( modelNumber ) ;
87
- }
81
+ string modelNumber = model . Substring ( 3 ) ;
82
+ if ( modelNumber . StartsWith ( "CPU" ) )
83
+ modelNumber = modelNumber . Substring ( 3 ) . Trim ( ) ;
84
+ if ( modelNumber . Contains ( "CPU" ) )
85
+ modelNumber = modelNumber . Substring ( 0 , modelNumber . IndexOf ( "CPU" , StringComparison . Ordinal ) ) . Trim ( ) ;
86
+ return ParseIntelCoreMicroarchitecture ( modelNumber ) ;
88
87
}
89
-
90
- return null ;
91
88
}
92
89
93
- private static readonly Lazy < Dictionary < string , string > > KnownMicroarchitectures = new Lazy < Dictionary < string , string > > ( ( ) =>
90
+ return null ;
91
+ }
92
+
93
+ private static readonly Lazy < Dictionary < string , string > > KnownMicroarchitectures = new Lazy < Dictionary < string , string > > ( ( ) =>
94
+ {
95
+ var data = ResourceHelper . LoadResource ( "BenchmarkDotNet.Environments.microarchitectures.txt" ) . Split ( '\r ' , '\n ' ) ;
96
+ var dictionary = new Dictionary < string , string > ( ) ;
97
+ string ? currentMicroarchitecture = null ;
98
+ foreach ( string line in data )
94
99
{
95
- var data = ResourceHelper . LoadResource ( "BenchmarkDotNet.Environments.microarchitectures.txt" ) . Split ( '\r ' , '\n ' ) ;
96
- var dictionary = new Dictionary < string , string > ( ) ;
97
- string ? currentMicroarchitecture = null ;
98
- foreach ( string line in data )
100
+ if ( line . StartsWith ( "//" ) || string . IsNullOrWhiteSpace ( line ) )
101
+ continue ;
102
+ if ( line . StartsWith ( "#" ) )
99
103
{
100
- if ( line . StartsWith ( "//" ) || string . IsNullOrWhiteSpace ( line ) )
101
- continue ;
102
- if ( line . StartsWith ( "#" ) )
103
- {
104
- currentMicroarchitecture = line . Substring ( 1 ) . Trim ( ) ;
105
- continue ;
106
- }
107
-
108
- string modelNumber = line . Trim ( ) ;
109
- if ( dictionary . ContainsKey ( modelNumber ) )
110
- throw new Exception ( $ "{ modelNumber } is defined twice in microarchitectures.txt") ;
111
- if ( currentMicroarchitecture == null )
112
- throw new Exception ( $ "{ modelNumber } doesn't have defined microarchitecture in microarchitectures.txt") ;
113
- dictionary [ modelNumber ] = currentMicroarchitecture ;
104
+ currentMicroarchitecture = line . Substring ( 1 ) . Trim ( ) ;
105
+ continue ;
114
106
}
115
107
116
- return dictionary ;
117
- } ) ;
108
+ string modelNumber = line . Trim ( ) ;
109
+ if ( dictionary . ContainsKey ( modelNumber ) )
110
+ throw new Exception ( $ "{ modelNumber } is defined twice in microarchitectures.txt") ;
111
+ if ( currentMicroarchitecture == null )
112
+ throw new Exception ( $ "{ modelNumber } doesn't have defined microarchitecture in microarchitectures.txt") ;
113
+ dictionary [ modelNumber ] = currentMicroarchitecture ;
114
+ }
118
115
119
- // see http://www.intel.com/content/www/us/en/processors/processor-numbers.html
120
- [ SuppressMessage ( "ReSharper" , "StringLiteralTypo" ) ]
121
- internal static string ? ParseIntelCoreMicroarchitecture ( string modelNumber )
122
- {
123
- if ( KnownMicroarchitectures . Value . TryGetValue ( modelNumber , out string ? microarchitecture ) )
124
- return microarchitecture ;
116
+ return dictionary ;
117
+ } ) ;
118
+
119
+ // see http://www.intel.com/content/www/us/en/processors/processor-numbers.html
120
+ [ SuppressMessage ( "ReSharper" , "StringLiteralTypo" ) ]
121
+ internal static string ? ParseIntelCoreMicroarchitecture ( string modelNumber )
122
+ {
123
+ if ( KnownMicroarchitectures . Value . TryGetValue ( modelNumber , out string ? microarchitecture ) )
124
+ return microarchitecture ;
125
125
126
- if ( modelNumber . Length >= 3 && modelNumber . Substring ( 0 , 3 ) . All ( char . IsDigit ) &&
127
- ( modelNumber . Length == 3 || ! char . IsDigit ( modelNumber [ 3 ] ) ) )
128
- return "Nehalem" ;
129
- if ( modelNumber . Length >= 4 && modelNumber . Substring ( 0 , 4 ) . All ( char . IsDigit ) )
126
+ if ( modelNumber . Length >= 3 && modelNumber . Substring ( 0 , 3 ) . All ( char . IsDigit ) &&
127
+ ( modelNumber . Length == 3 || ! char . IsDigit ( modelNumber [ 3 ] ) ) )
128
+ return "Nehalem" ;
129
+ if ( modelNumber . Length >= 4 && modelNumber . Substring ( 0 , 4 ) . All ( char . IsDigit ) )
130
+ {
131
+ char generation = modelNumber [ 0 ] ;
132
+ switch ( generation )
130
133
{
131
- char generation = modelNumber [ 0 ] ;
132
- switch ( generation )
133
- {
134
- case '2' :
135
- return "Sandy Bridge" ;
136
- case '3' :
137
- return "Ivy Bridge" ;
138
- case '4' :
139
- return "Haswell" ;
140
- case '5' :
141
- return "Broadwell" ;
142
- case '6' :
143
- return "Skylake" ;
144
- case '7' :
145
- return "Kaby Lake" ;
146
- case '8' :
147
- return "Coffee Lake" ;
148
- default :
149
- return null ;
150
- }
134
+ case '2' :
135
+ return "Sandy Bridge" ;
136
+ case '3' :
137
+ return "Ivy Bridge" ;
138
+ case '4' :
139
+ return "Haswell" ;
140
+ case '5' :
141
+ return "Broadwell" ;
142
+ case '6' :
143
+ return "Skylake" ;
144
+ case '7' :
145
+ return "Kaby Lake" ;
146
+ case '8' :
147
+ return "Coffee Lake" ;
148
+ default :
149
+ return null ;
151
150
}
152
- return null ;
153
151
}
152
+ return null ;
154
153
}
155
154
}
0 commit comments