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
127
128
129
130
|
#!/usr/bin/env python
#import os
#import re
#import fnmatch
#import shutil as sh
#import sys
#import csv
#from optparse import OptionParser
#
#from machines import machines
import numpy as np
class Topology:
ncpus, root, leaves, dist_mat = 0, None, None, None
levels = ['L1', 'L2', 'L3', 'MEM', 'SYSTEM']
overhead = None
class Node:
idx, name, parent, children = 0, 'Unk', None, None
def __init__(self, idx, name, parent = None):
self.idx = idx
self.name = name
self.parent = parent
self.children = []
# def __repr__(self):
# return self.name + '_' + str(self.idx)
def __build_level_above(self, machine, l, child_nodes):
key = 'n' + l
if key in machine:
cluster_sz = machine[key]
else:
cluster_sz = 1
nchildren = len(child_nodes)
nodes = [self.Node(idx, l) for idx in range(nchildren/cluster_sz)]
for i in range(len(child_nodes)):
child_nodes[i].parent = nodes[i/cluster_sz]
nodes[i/cluster_sz].children.append(child_nodes[i])
return nodes
def __find_dist(self, a, b):
if a != b:
# pass-through (ex. as CPU is to private L1)
if len(a.parent.children) == 1:
return self.__find_dist(a.parent, b.parent)
else:
return 1 + self.__find_dist(a.parent, b.parent)
return 0
def __build_dist_matrix(self):
dist_mat = np.empty([self.ncpus, self.ncpus], int)
for i in range(self.ncpus):
for j in range(i, self.ncpus):
dist_mat[i,j] = dist_mat[j,i] = self.__find_dist(self.leaves[i], self.leaves[j])
return dist_mat
def __init__(self, machine):
self.ncpus = machine['sockets']*machine['cores_per_socket']
self.machine = machine
# build the Topology bottom up
self.leaves = [self.Node(idx, 'CPU') for idx in range(self.ncpus)]
nodes = self.leaves
for l in self.levels:
nodes = self.__build_level_above(machine, l, nodes)
self.root = nodes
self.dist_mat = self.__build_dist_matrix()
# def __repr_level(self, node, stem, buf):
# spacing = 3
# buf += stem + node.name + '_' + str(node.idx) + '\n'
# for c in node.children:
# buf = self.__repr_level(c, stem + ' '*spacing, buf)
# return buf
# def __repr__(self):
# buf = self.__repr_level(self.root[0], '', '')
# return buf
def max_wss(self):
# returns the maximum amount of data a CPU
# can store in its cache for a task on a
# __single socket__
# cache levels in reverse order
levels = ['L3', 'L2', 'L1']
size = 0
if self.machine['inclusive'] == 1:
|