| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  | module Hardware | 
					
						
							|  |  |  |   class CPU | 
					
						
							| 
									
										
										
										
											2016-05-09 09:41:30 +02:00
										 |  |  |     class << self | 
					
						
							|  |  |  |       def cpuinfo | 
					
						
							|  |  |  |         @cpuinfo ||= File.read("/proc/cpuinfo") | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-09 09:41:30 +02:00
										 |  |  |       def family | 
					
						
							| 
									
										
										
										
											2016-07-29 20:02:26 -06:00
										 |  |  |         return :arm if arm? | 
					
						
							| 
									
										
										
										
											2017-11-29 11:44:59 -08:00
										 |  |  |         return :ppc if ppc? | 
					
						
							| 
									
										
										
										
											2016-07-29 20:02:26 -06:00
										 |  |  |         return :dunno unless intel? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-29 20:02:26 -06:00
										 |  |  |         # See https://software.intel.com/en-us/articles/intel-architecture-and-processor-identification-with-cpuid-model-and-family-numbers | 
					
						
							|  |  |  |         cpu_family = cpuinfo[/^cpu family\s*: ([0-9]+)/, 1].to_i | 
					
						
							|  |  |  |         cpu_model = cpuinfo[/^model\s*: ([0-9]+)/, 1].to_i | 
					
						
							|  |  |  |         case cpu_family | 
					
						
							|  |  |  |         when 0x06
 | 
					
						
							|  |  |  |           case cpu_model | 
					
						
							|  |  |  |           when 0x3a, 0x3e
 | 
					
						
							|  |  |  |             :ivybridge | 
					
						
							|  |  |  |           when 0x2a, 0x2d
 | 
					
						
							|  |  |  |             :sandybridge | 
					
						
							|  |  |  |           when 0x25, 0x2c, 0x2f
 | 
					
						
							|  |  |  |             :westmere | 
					
						
							|  |  |  |           when 0x1e, 0x1a, 0x2e
 | 
					
						
							|  |  |  |             :nehalem | 
					
						
							|  |  |  |           when 0x17, 0x1d
 | 
					
						
							|  |  |  |             :penryn | 
					
						
							|  |  |  |           when 0x0f, 0x16
 | 
					
						
							|  |  |  |             :merom | 
					
						
							|  |  |  |           when 0x0d
 | 
					
						
							|  |  |  |             :dothan | 
					
						
							|  |  |  |           when 0x36, 0x26, 0x1c
 | 
					
						
							|  |  |  |             :atom | 
					
						
							|  |  |  |           when 0x3c, 0x3f, 0x46
 | 
					
						
							|  |  |  |             :haswell | 
					
						
							|  |  |  |           when 0x3d, 0x47, 0x4f, 0x56
 | 
					
						
							|  |  |  |             :broadwell | 
					
						
							| 
									
										
										
										
											2017-03-10 16:32:41 -06:00
										 |  |  |           when 0x5e
 | 
					
						
							|  |  |  |             :skylake | 
					
						
							| 
									
										
										
										
											2016-12-18 14:50:38 -08:00
										 |  |  |           when 0x8e
 | 
					
						
							|  |  |  |             :kabylake | 
					
						
							| 
									
										
										
										
											2016-07-29 20:02:26 -06:00
										 |  |  |           else | 
					
						
							| 
									
										
										
										
											2018-07-13 08:54:08 +01:00
										 |  |  |             :dunno | 
					
						
							| 
									
										
										
										
											2016-07-29 20:02:26 -06:00
										 |  |  |           end | 
					
						
							|  |  |  |         when 0x0f
 | 
					
						
							|  |  |  |           case cpu_model | 
					
						
							|  |  |  |           when 0x06
 | 
					
						
							|  |  |  |             :presler | 
					
						
							|  |  |  |           when 0x03, 0x04
 | 
					
						
							|  |  |  |             :prescott | 
					
						
							|  |  |  |           else | 
					
						
							| 
									
										
										
										
											2018-07-13 08:54:08 +01:00
										 |  |  |             :dunno | 
					
						
							| 
									
										
										
										
											2016-07-29 20:02:26 -06:00
										 |  |  |           end | 
					
						
							|  |  |  |         else | 
					
						
							| 
									
										
										
										
											2018-07-13 08:54:08 +01:00
										 |  |  |           :dunno | 
					
						
							| 
									
										
										
										
											2016-07-29 20:02:26 -06:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2016-05-09 09:41:30 +02:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-09 09:41:30 +02:00
										 |  |  |       def flags | 
					
						
							| 
									
										
										
										
											2017-11-29 11:44:59 -08:00
										 |  |  |         @flags ||= cpuinfo[/^(flags|Features).*/, 0]&.split | 
					
						
							|  |  |  |         @flags ||= [] | 
					
						
							| 
									
										
										
										
											2016-05-09 09:41:30 +02:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-09 09:41:30 +02:00
										 |  |  |       # Compatibility with Mac method, which returns lowercase symbols | 
					
						
							|  |  |  |       # instead of strings | 
					
						
							|  |  |  |       def features | 
					
						
							|  |  |  |         @features ||= flags[1..-1].map(&:intern) | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-22 11:19:24 +02:00
										 |  |  |       %w[aes altivec avx avx2 lm ssse3 sse4_2].each do |flag| | 
					
						
							| 
									
										
										
										
											2016-05-09 09:41:30 +02:00
										 |  |  |         define_method(flag + "?") { flags.include? flag } | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2017-07-05 12:36:39 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       def sse3? | 
					
						
							|  |  |  |         flags.include?("pni") || flags.include?("sse3") | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-22 11:19:24 +02:00
										 |  |  |       def sse4? | 
					
						
							|  |  |  |         flags.include? "sse4_1" | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |