forked from andikleen/pmu-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cputop.py
executable file
·126 lines (111 loc) · 3.3 KB
/
cputop.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/env python
# query cpu topology and print all matching cpu numbers
# cputop "query" ["format"]
# query is a python expression, using variables:
# socket, core, thread, type, cpu
# or "offline" to query all offline cpus
# type can be "atom" or "core"
# cpu is the cpu number
# format is a printf format with %d
# %d will be replaced with the cpu number
# format can be offline to offline the cpu or online to online
# Author: Andi Kleen
from __future__ import print_function
import sys
import os
import re
import argparse
import glob
def numfile(fn):
f = open(fn, "r")
v = int(f.read())
f.close()
return v
outstr = ""
def output(p, fmt):
if fmt:
if fmt == "taskset":
global outstr
if outstr:
outstr += ","
else:
outstr += "taskset -c "
outstr += "%d" % p
else:
print(fmt % (p,))
else:
print(p)
ap = argparse.ArgumentParser(description='''
query cpu topology and print all matching cpu numbers
cputop "query" ["format"]
query is a python expression, using variables:
socket, core, thread, type, cpu
type is "core" or "atom" on a hybrid system
cpu is the cpu number
or "offline" to query all offline cpus
format is a printf format with %d
%d will be replaced with the cpu number, or online/offline
to generate online/offline commands, or taskset to generate taskset command line''',
epilog='''
Examples:
print all cores on socket 0
cputop "socket == 0"
print all first threads in each core on socket 0
cputop "thread == 0 and socket == 0"
disable all second threads (disable hyper threading)
cputop "thread == 1" offline
reenable all offlined cpus
cputop offline online
print all online cpus
cputop True ''', formatter_class=argparse.RawTextHelpFormatter)
ap.add_argument('expr', help='python expression with socket/core/thread')
ap.add_argument('fmt', help='Output format string with %%d, or online/offline', nargs='?')
args = ap.parse_args()
special = {
"offline": "echo 0 > /sys/devices/system/cpu/cpu%d/online",
"online": "echo 1 > /sys/devices/system/cpu/cpu%d/online",
}
if args.fmt in special:
args.fmt = special[args.fmt]
types = dict()
for fn in glob.glob("/sys/devices/cpu_*/cpus"):
type = os.path.basename(fn.replace("/cpus", "")).replace("cpu_","")
cpus = open(fn).read()
for j in cpus.split(","):
m = re.match(r'(\d+)(-\d+)?', j)
if m.group(2):
for k in range(int(m.group(1)), int(m.group(2)[1:])+1):
types[k] = type
else:
types[int(m.group(1))] = type
base = "/sys/devices/system/cpu/"
p = {}
l = os.listdir(base)
for d in l:
m = re.match(r"cpu([0-9]+)", d)
if not m:
continue
proc = int(m.group(1))
top = base + d + "/topology"
if not os.path.exists(top):
if args.expr == "offline":
output(proc, args.fmt)
continue
socket = numfile(top + "/physical_package_id")
core = numfile(top + "/core_id")
n = 0
while (socket, core, n) in p:
n += 1
p[(socket, core, n)] = proc
if args.expr == "offline":
sys.exit(0)
for j in sorted(p.keys()):
socket, core, thread = j
cpu = p[j]
type = "any"
if cpu in types:
type = types[cpu]
if eval(args.expr):
output(p[j], args.fmt)
if outstr:
print(outstr)