Class: ComputeUnit::Cpu

Inherits:
ComputeBase show all
Defined in:
lib/compute_unit/cpu.rb

Constant Summary collapse

DEVICE_CLASS =
'060000'
DEVICE_CLASS_NAME =
'CPU'
VOLTAGE_MSR =
0x198

Constants inherited from ComputeBase

ComputeUnit::ComputeBase::CACHE_TIMEOUT

Constants inherited from Device

Device::PROC_PATH, Device::SYSFS_DEVICES_PATH

Instance Attribute Summary

Attributes inherited from ComputeBase

#compute_type, #index, #meta, #power_offset, #serial, #timestamp, #type, #uuid

Attributes inherited from Device

#device_class_id, #device_id, #device_path, #device_vendor_id, #subsystem_device_id, #subsystem_vendor_id, #vendor

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ComputeBase

#attached_processes, compute_classes, #device_class_name, #experimental_on?, #expired_metadata?, #micro_formatter, #top_processes

Methods included from Logger

color, log_file, log_level, logger, #logger

Methods included from Formatters

#micro_formatter, #value_micro_formatter

Methods inherited from Device

device, device_class, device_lookup, device_vendor, #expired_metadata?, #generic_model, #hwmon_path, #lock_rom, logger, manual_device_database, manual_device_lookup, manual_vendor_lookup, manual_vendors, name_map, name_translation, pci_database, #read_file, #read_hwmon_data, #read_kernel_setting, read_kernel_setting, #rom_data, #rom_path, subsystem_device, subsystem_device_lookup, subsystem_vendor, subsystem_vendor_lookup, #sysfs_model_name, system_checksum, #to_json, #unlock_rom, vendor_lookup, #write_hwmon_data, write_kernel_setting, #write_kernel_setting

Methods included from Utils

check_for_root, #root?, root?

Constructor Details

#initialize(_device_path, opts) ⇒ Cpu

Returns a new instance of Cpu.



169
170
171
172
173
174
175
# File 'lib/compute_unit/cpu.rb', line 169

def initialize(_device_path, opts)
  super
  @type = :CPU
  @pci_loc = device_path,
             @index = opts[:index].to_i
  @power_offset = 0
end

Class Method Details

.attached_processes(field = :pctcpu, _filter = nil) ⇒ Array

Returns - an array of attached processes.

Parameters:

  • field (Symbol) (defaults to: :pctcpu)
    • the field to sort by

  • filter (Regex)
    • if supplied filter out devices from fd list

Returns:

  • (Array)
    • an array of attached processes



26
27
28
# File 'lib/compute_unit/cpu.rb', line 26

def self.attached_processes(field = :pctcpu, _filter = nil)
  Sys::ProcTable.ps(smaps: false).sort_by(&field)
end

.create_from_path(device_path, index) ⇒ Object



177
178
179
180
181
182
183
184
185
186
187
# File 'lib/compute_unit/cpu.rb', line 177

def self.create_from_path(device_path, index)
  opts = {
    device_class_id: device_class(device_path),
    device_id: device(device_path),
    device_vendor_id: device_vendor(device_path),
    subsystem_vendor_id: subsystem_vendor(device_path),
    subsystem_device_id: subsystem_device(device_path),
    index: index
  }
  new(device_path, opts)
end

.devicesArray

Returns - returns a list of device paths of all devices considered for display.

Returns:

  • (Array)
    • returns a list of device paths of all devices considered for display



12
13
14
15
16
# File 'lib/compute_unit/cpu.rb', line 12

def self.devices
  ComputeUnit::ComputeBase.devices.find_all do |device|
    ComputeUnit::Device.device_class(device) == DEVICE_CLASS
  end
end

.find_all(_use_opencl = false) ⇒ Object



189
190
191
192
193
# File 'lib/compute_unit/cpu.rb', line 189

def self.find_all(_use_opencl = false)
  devices.sort.map.with_index do |device_path, index|
    create_from_path(device_path, index)
  end
end

Instance Method Details

#base_hwmon_pathString

Returns the path of the hwmon path for monitoring temps.

Returns:

  • (String)

    the path of the hwmon path for monitoring temps



95
96
97
# File 'lib/compute_unit/cpu.rb', line 95

def base_hwmon_path
  File.join(ComputeUnit::SYSFS_PATH, 'devices/platform/coretemp.0/hwmon')
end

#current_freq_mhzFloat

Returns - current mhz of cpu.

Returns:

  • (Float)
    • current mhz of cpu



80
81
82
# File 'lib/compute_unit/cpu.rb', line 80

def current_freq_mhz
  raw_cpu_data[:cpu_mhz].to_f.round(0)
end

#fanObject



124
125
126
# File 'lib/compute_unit/cpu.rb', line 124

def fan
  2500 # until we can calculate fan speed
end

#makeString

Returns - the maker of the cpu.

Returns:

  • (String)
    • the maker of the cpu



60
61
62
# File 'lib/compute_unit/cpu.rb', line 60

def make
  raw_cpu_data[:vendor_id]
end

#max_freq_mhzFloat

Returns - max mhz of cpu.

Returns:

  • (Float)
    • max mhz of cpu



85
86
87
# File 'lib/compute_unit/cpu.rb', line 85

def max_freq_mhz
  raw_cpu_data[:cpu_max_mhz].to_f.round(0)
end

#mem_tempObject



128
129
130
# File 'lib/compute_unit/cpu.rb', line 128

def mem_temp
  0 # until we can get the mem temp
end

#metricsObject



150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/compute_unit/cpu.rb', line 150

def metrics
  {
    temp: temp,
    minFreqMhz: min_freq_mhz,
    maxFreqMhz: max_freq_mhz,
    currentFreqMhz: current_freq_mhz,
    model: model,
    make: make,
    numCores: num_cores,
    numThreads: num_threads,
    nproc: nproc,
    temps: temps
  }
end

#min_freq_mhzFloat

Returns - current min of cpu.

Returns:

  • (Float)
    • current min of cpu



90
91
92
# File 'lib/compute_unit/cpu.rb', line 90

def min_freq_mhz
  raw_cpu_data[:cpu_min_mhz].to_f.round(0)
end

#modelString

Returns - the model / name of the cpu.

Returns:

  • (String)
    • the model / name of the cpu



50
51
52
# File 'lib/compute_unit/cpu.rb', line 50

def model
  raw_cpu_data[:model_name]
end

#nameString

Returns - the model / name of the cpu.

Returns:

  • (String)
    • the model / name of the cpu



55
56
57
# File 'lib/compute_unit/cpu.rb', line 55

def name
  model
end

#nprocInteger

Returns - the number of cpus.

Returns:

  • (Integer)
    • the number of cpus



75
76
77
# File 'lib/compute_unit/cpu.rb', line 75

def nproc
  raw_cpu_data[:cpus].to_i
end

#num_coresInteger

Returns - the number of cores.

Returns:

  • (Integer)
    • the number of cores



65
66
67
# File 'lib/compute_unit/cpu.rb', line 65

def num_cores
  raw_cpu_data[:cores_per_socket].to_i
end

#num_threadsInteger

Returns - the number of threads.

Returns:

  • (Integer)
    • the number of threads



70
71
72
# File 'lib/compute_unit/cpu.rb', line 70

def num_threads
  raw_cpu_data[:threads_per_core].to_i
end

#pci_locObject



132
133
134
# File 'lib/compute_unit/cpu.rb', line 132

def pci_loc
  device_path
end

#powerObject



120
121
122
# File 'lib/compute_unit/cpu.rb', line 120

def power
  ENV.fetch('CPU_POWER', 60) # until we can calculate power we will just use 60
end

#statusObject



116
117
118
# File 'lib/compute_unit/cpu.rb', line 116

def status
  0
end

#status_infoObject



136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/compute_unit/cpu.rb', line 136

def status_info
  { index: "CPU#{index}",
    name: model,
    bios: 'N/A',
    core_clock: current_freq_mhz,
    memory_clock: 'N/A',
    power: power,
    fan: fan,
    core_volt: voltage,
    temp: temp,
    mem_temp: mem_temp,
    status: status }
end

#tempInteger

Returns - the temperature of the cpu package in Celsius.

Returns:

  • (Integer)
    • the temperature of the cpu package in Celsius



112
113
114
# File 'lib/compute_unit/cpu.rb', line 112

def temp
  read_hwmon_data('temp1_input', 0).to_f.round(0) / 1000
end

#tempsHash

Returns - a hash of temp readings and their labels.

Examples:

temps => :core_1=>31, :package_id_0=>27

Returns:

  • (Hash)
    • a hash of temp readings and their labels



101
102
103
104
105
106
107
108
109
# File 'lib/compute_unit/cpu.rb', line 101

def temps
  Dir.glob(File.join(hwmon_path, 'temp*_label')).each_with_object({}) do |label_file, acc|
    temp_file = label_file.sub('label', 'input')
    label = normalize_name(read_file(label_file))
    reading = read_file(temp_file).to_f.round(0) / 1000
    acc[label] = reading
    acc
  end
end

#to_hObject



165
166
167
# File 'lib/compute_unit/cpu.rb', line 165

def to_h
  super.merge(metrics)
end

#utilizationObject



18
19
20
# File 'lib/compute_unit/cpu.rb', line 18

def utilization
  1 # until we can calculate this.  Is loadavg a good metric? or load / cpus
end

#voltage(processor_id = 0) ⇒ Object

Parameters:

  • processor_id (Integer) (defaults to: 0)
    • the id of the cpu



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/compute_unit/cpu.rb', line 32

def voltage(processor_id = 0)
  file = "/dev/cpu/#{processor_id}/msr"
  return 0 unless File.exist?(file)

  # read 8 bytes, then unpack it by turning it into an integer
  # make it a binary string, pluck out some specific bits, then
  # convert it back to an integer
  # divide by 8192 to give the voltage
  # lowbit = 32
  # highbit = 47
  # bits = 47 - 32 + 1 # we want to read bits 32-47
  msr = IO.new IO.sysopen(file, 'rb')
  msr.sysseek(VOLTAGE_MSR)
  data, = msr.sysread(8).unpack('q')
  format('%.2f', ((data >> 32) / 8192.to_f))
end