Top: each CPU's own wattage on a two-socket machine, its threads folded under it
Per-package RAPL watts in the sample, the process table and as cpu.package.N.power sensors. The socket rows collapse with an arrow; the fold is remembered per browser. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
1e2dcacb2c
commit
e9a87af5e8
@@ -95,30 +95,41 @@ func readRAPL(root string, dirs []string) ([]raplCount, bool) {
|
||||
// is carried across its range. One that went backwards with no known range, or a set of
|
||||
// counters that changed between readings, gives no answer rather than a wrong one.
|
||||
func raplWatts(prev, cur []raplCount, max map[string]uint64, dt float64) (float64, bool) {
|
||||
if dt <= 0 || len(prev) == 0 || len(prev) != len(cur) {
|
||||
return 0, false
|
||||
each, ok := raplWattsEach(prev, cur, max, dt)
|
||||
var w float64
|
||||
for _, x := range each {
|
||||
w += x
|
||||
}
|
||||
var uj float64
|
||||
return w, ok
|
||||
}
|
||||
|
||||
// raplWattsEach is raplWatts per counter: one package each.
|
||||
func raplWattsEach(prev, cur []raplCount, max map[string]uint64, dt float64) ([]float64, bool) {
|
||||
if dt <= 0 || len(prev) == 0 || len(prev) != len(cur) {
|
||||
return nil, false
|
||||
}
|
||||
out := make([]float64, len(cur))
|
||||
for i := range cur {
|
||||
if cur[i].Dir != prev[i].Dir {
|
||||
return 0, false
|
||||
return nil, false
|
||||
}
|
||||
if cur[i].UJ >= prev[i].UJ {
|
||||
uj += float64(cur[i].UJ - prev[i].UJ)
|
||||
out[i] = float64(cur[i].UJ-prev[i].UJ) / 1e6 / dt
|
||||
continue
|
||||
}
|
||||
m := max[cur[i].Dir]
|
||||
if m == 0 || prev[i].UJ > m {
|
||||
return 0, false
|
||||
return nil, false
|
||||
}
|
||||
uj += float64(m - prev[i].UJ + cur[i].UJ)
|
||||
out[i] = float64(m-prev[i].UJ+cur[i].UJ) / 1e6 / dt
|
||||
}
|
||||
return uj / 1e6 / dt, true
|
||||
return out, true
|
||||
}
|
||||
|
||||
// cpuPower is the CPU packages' power since the previous sample, in watts; 0 when this
|
||||
// machine has no counters or no way to read them.
|
||||
func (c *Collector) cpuPower(now time.Time) float64 {
|
||||
// machine has no counters or no way to read them. On a machine with more than one package
|
||||
// it also gives each one's, indexed by package id (the socket).
|
||||
func (c *Collector) cpuPower(now time.Time) (float64, []float64) {
|
||||
p := &c.power
|
||||
if !p.probed {
|
||||
p.probed = true
|
||||
@@ -131,7 +142,7 @@ func (c *Collector) cpuPower(now time.Time) float64 {
|
||||
}
|
||||
}
|
||||
if len(p.dirs) == 0 {
|
||||
return 0
|
||||
return 0, nil
|
||||
}
|
||||
var cur []raplCount
|
||||
ok := false
|
||||
@@ -148,14 +159,40 @@ func (c *Collector) cpuPower(now time.Time) float64 {
|
||||
}
|
||||
if !ok {
|
||||
p.prev = nil
|
||||
return 0
|
||||
return 0, nil
|
||||
}
|
||||
w, good := raplWatts(p.prev, cur, p.max, now.Sub(p.prevAt).Seconds())
|
||||
each, good := raplWattsEach(p.prev, cur, p.max, now.Sub(p.prevAt).Seconds())
|
||||
p.prev, p.prevAt = cur, now
|
||||
if !good {
|
||||
return 0
|
||||
return 0, nil
|
||||
}
|
||||
return round1(w)
|
||||
var w float64
|
||||
for _, x := range each {
|
||||
w += x
|
||||
}
|
||||
return round1(w), perPackage(cur, each)
|
||||
}
|
||||
|
||||
// perPackage puts each counter's watts at its package's id — intel-rapl:1 is "package-1" —
|
||||
// and is nil for a single package, whose figure is the total.
|
||||
func perPackage(cur []raplCount, each []float64) []float64 {
|
||||
if len(cur) < 2 {
|
||||
return nil
|
||||
}
|
||||
var out []float64
|
||||
for i, c := range cur {
|
||||
id := i
|
||||
if n, ok := strings.CutPrefix(strings.TrimSpace(readStr(filepath.Join(raplRoot, c.Dir, "name"))), "package-"); ok {
|
||||
if v, err := strconv.Atoi(n); err == nil && v >= 0 && v < 64 {
|
||||
id = v
|
||||
}
|
||||
}
|
||||
for len(out) <= id {
|
||||
out = append(out, 0)
|
||||
}
|
||||
out[id] = round1(each[i])
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// energyHelper is the root child that answers each newline with the package counters, one
|
||||
|
||||
Reference in New Issue
Block a user