ENH make gpu power limits configurable
This commit is contained in:
parent
b5920374a7
commit
1ab23d039b
|
@ -138,6 +138,23 @@ let FileSystem =
|
|||
, default.geometry = FSGeo::{=}
|
||||
}
|
||||
|
||||
let GPUPower =
|
||||
{-
|
||||
Controls how the GPU will be queries so it can go to sleep when 'idle'.
|
||||
|
||||
freq_limit: only query the GPU every 'cycle_seconds' when frequency is below
|
||||
this value; this should be a sensible value representing and
|
||||
'idle' gpu state.
|
||||
cycle_seconds: the number of seconds to query the GPU when below the idle
|
||||
frequency limit; note that this must be long enough to let
|
||||
the GPU go to sleep when it actually is ready to sleep, but
|
||||
not so long that the next query will miss too much activity
|
||||
in the case the GPU doesn't shut off
|
||||
-}
|
||||
{ Type = { freq_limit : Natural, cycle_seconds : Natural }
|
||||
, default = { freq_limit = 250, cycle_seconds = 10 }
|
||||
}
|
||||
|
||||
let Graphics =
|
||||
{-
|
||||
Defines Graphics module configuration
|
||||
|
@ -158,8 +175,9 @@ let Graphics =
|
|||
, show_mem_util : Bool
|
||||
, show_vid_util : Bool
|
||||
, geometry : GfxGeo.Type
|
||||
, power : GPUPower.Type
|
||||
}
|
||||
, default.geometry = GfxGeo::{=}
|
||||
, default = { geometry = GfxGeo::{=}, power = GPUPower::{=} }
|
||||
}
|
||||
|
||||
let Memory =
|
||||
|
|
|
@ -20,29 +20,43 @@ return function(update_freq, config, common, width, point)
|
|||
|
||||
i_o.assert_exe_exists(NVIDIA_EXE)
|
||||
|
||||
-- vars to process the nv settings glob
|
||||
--
|
||||
local mk_query_cmd = function(props)
|
||||
return string.format(
|
||||
'%s --query-gpu=%s --format=csv,noheader,nounits',
|
||||
NVIDIA_EXE,
|
||||
pure.collapse(props, ',')
|
||||
)
|
||||
end
|
||||
|
||||
local NV_QUERY = NVIDIA_EXE..
|
||||
' --query-gpu=memory.used,memory.total,temperature.gpu,clocks.gr,clocks.mem,utilization.gpu,utilization.decoder'..
|
||||
' --format=csv,noheader,nounits'
|
||||
-- TODO also use encoder for video util?
|
||||
-- TODO add video clock speed?
|
||||
local query_stats = mk_query_cmd(
|
||||
{
|
||||
'memory.used',
|
||||
'temperature.gpu',
|
||||
'clocks.gr',
|
||||
'clocks.mem',
|
||||
'utilization.gpu',
|
||||
'utilization.decoder'
|
||||
}
|
||||
)
|
||||
|
||||
local NV_REGEX = '(%d+), (%d+), (%d+), (%d+), (%d+), (%d+), (%d+)'
|
||||
local NV_REGEX = '(%d+), (%d+), (%d+), (%d+), (%d+), (%d+)'
|
||||
|
||||
local mod_state = {
|
||||
error = false,
|
||||
total_memory = 0,
|
||||
gpu_frequency = 0,
|
||||
memory_frequency = 0,
|
||||
used_memory = 0,
|
||||
total_memory = 0,
|
||||
temp_reading = 0,
|
||||
gpu_utilization = 0,
|
||||
vid_utilization = 0
|
||||
}
|
||||
|
||||
local sleep_token = 0
|
||||
local sleep_limit = 10
|
||||
local gpu_idle_freq_limit = 250
|
||||
local sleep_limit = config.power.cycle_seconds
|
||||
local gpu_idle_freq_limit = config.power.freq_limit
|
||||
|
||||
-- TODO ensure this file exists
|
||||
local runtime_status_file = config.dev_power..'/runtime_status'
|
||||
|
@ -74,12 +88,11 @@ return function(update_freq, config, common, width, point)
|
|||
sleep_token = 0
|
||||
end
|
||||
if is_active and want_nvidia_query and sleep_token == 0 then
|
||||
local nvidia_settings_glob = i_o.execute_cmd(NV_QUERY)
|
||||
local nvidia_settings_glob = i_o.execute_cmd(query_stats)
|
||||
if nvidia_settings_glob == nil then
|
||||
mod_state.error = 'Error'
|
||||
else
|
||||
mod_state.used_memory,
|
||||
mod_state.total_memory,
|
||||
mod_state.temp_reading,
|
||||
mod_state.gpu_frequency,
|
||||
mod_state.memory_frequency,
|
||||
|
@ -89,6 +102,11 @@ return function(update_freq, config, common, width, point)
|
|||
mod_state.gpu_frequency = tonumber(mod_state.gpu_frequency)
|
||||
mod_state.error = false
|
||||
end
|
||||
-- query total memory if we need it (do this here so we don't turn on
|
||||
-- the gpu every time we start conky)
|
||||
if mod_state.total_memory == 0 and config.show_mem_util then
|
||||
mod_state.total_memory = tonumber(i_o.execute_cmd(mk_query_cmd({'memory.total'})))
|
||||
end
|
||||
elseif is_active then
|
||||
mod_state.error = false
|
||||
else
|
||||
|
|
52
src/pure.lua
52
src/pure.lua
|
@ -4,6 +4,7 @@ local err = require 'err'
|
|||
|
||||
local __math_floor = math.floor
|
||||
local __table_insert = table.insert
|
||||
local __string_format = string.format
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- zippy functions
|
||||
|
@ -50,9 +51,52 @@ M.reduce = function(f, init, seq)
|
|||
end
|
||||
end
|
||||
|
||||
M.member = function(x, seq)
|
||||
return M.reduce(
|
||||
function(acc, next) return acc or next == x end,
|
||||
false,
|
||||
M.values(seq)
|
||||
)
|
||||
end
|
||||
|
||||
M.collapse = function(seq, delim)
|
||||
if #seq == 0 then
|
||||
return ''
|
||||
elseif #seq == 1 then
|
||||
return seq[1]
|
||||
else
|
||||
local init, rest = M.head(seq)
|
||||
return M.reduce(
|
||||
function(acc, next) return __string_format('%s%s%s', acc, delim, next) end,
|
||||
init,
|
||||
rest
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- mappy functions
|
||||
|
||||
M.keys = function(seq)
|
||||
local r = {}
|
||||
local n = 1
|
||||
for k, _ in pairs(seq) do
|
||||
r[n] = k
|
||||
n = n + 1
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
||||
M.values = function(seq)
|
||||
local r = {}
|
||||
local n = 1
|
||||
for _, v in pairs(seq) do
|
||||
r[n] = v
|
||||
n = n + 1
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
||||
M.map = function(f, seq, ...)
|
||||
local r = {}
|
||||
for i = 1, #seq do
|
||||
|
@ -144,6 +188,14 @@ M.length = function(tbl)
|
|||
return n
|
||||
end
|
||||
|
||||
M.head = function(seq)
|
||||
local r = {}
|
||||
for i = 2, #seq do
|
||||
r[i - 1] = seq[i]
|
||||
end
|
||||
return seq[1], r
|
||||
end
|
||||
|
||||
-- a stupid but composable function
|
||||
M.get = function(key, tbl)
|
||||
return tbl[key]
|
||||
|
|
Loading…
Reference in New Issue