0

I'm aware this question has been asked numerous times over but unfortunately none of the given answers seem to work for what I need.

Everyone seems to recommend /proc/stat however I can't seem to find 1 answer that works as expected:

as you can see here, core 0 reports being 16% used even though it's actually only 3% used in fact it doesn't matter if it's 100%, it still reports 16% with only a 0.01%-0.02% increase

I've also tested another approach with only $2+$4 +$5 rather than the whole range, but even that returned inaccurate results...

How do CPU monitors, like the graph above, derive their information??
because it doesn't appear to be through /proc/stat unless everyone's doing something wrong.

notable resources:

I've looked through much more, but they all pretty much point to the same things.

As for the script, I know it's a bit messy, I don't work with bash much, but here it is:

#!/bin/bash
H=($(awk '/MHz/{printf "%.2fGHz|", $4/1000}' /proc/cpuinfo))
A=($(awk 'FNR>1 && FNR<4 {
    i=$5+$6; printf "%d|%d\n", i, i+$2+$3+$4+$7+$8+$9
}' /proc/stat))
sleep 0.125
awk -v a="${A[*]}" -v h="${H[*]}" -v n="0" 'FNR>1 && FNR<4 {
    n++
    split(h,s,"|"); split(a,p,"|")
    i=$5+$6; t=(i+$2+$3+$4+$7+$8+$9)-p[n,1]
    printf "%s: %s %.2f%\n", $1, s[n], ((t-(i-p[n,0]))/t)*100
}' /proc/stat

pretty much all of it was followed from other answers...

If there's a better way to do any of this (such as merging cpuinfo with stat, or not needlessly splitting an array to prevent s[n] from reporting a scalar error, or even sleeping and re-reading within awk), by all means please improve. :)

James Brown
  • 36,089
  • 7
  • 43
  • 59
Tcll
  • 7,140
  • 1
  • 20
  • 23
  • What are `p[n,1]` and `p[n,0]`? – James Brown Mar 07 '20 at 18:38
  • @JamesBrown `p` is a split array from `A`: `split(a,p,"|")`, where the result is basically `( idle, total )`, check the python source from the first notable resource for more info. ;) – Tcll Mar 07 '20 at 21:00
  • if you dont understand `split()` (it threw me off as well), here's it's equivalent in python `p = tuple( v.split("|") for v in a )` or in other words `( "idle|total", ... ) -> ( ( idle, total ), ... )` – Tcll Mar 07 '20 at 21:06
  • I understand `split(a,p,"|")` after there will be `a[1],a[2]...` but not `a[1,1]` unless you explicitly define it which I can't see you doing. – James Brown Mar 07 '20 at 21:23
  • right because the result from `a[1]` is `"idle|total"` (or at least it should be, where bash doesn't agree), which I've already tried every way I could think of to create `A` as a 2D array, and I can't find anything on creating 2D arrays, or what's even worse is you can't even access `a[n]` because that thinks `a` is a scalar. – Tcll Mar 07 '20 at 21:28

0 Answers0