mirror of
https://github.com/google/cadvisor.git
synced 2021-05-12 18:32:21 +03:00
add uncore cache in topology.
In some architecture, l3 cache(or llc) is not shared among the whole node but among some cores, it is neccessary to distinguish cache-in-core, uncore-cache, cache-in-node for runtime awareness and performance impact analysis. Signed-off-by: ranchochen <ranchochen@tencent.com>
This commit is contained in:
@@ -47,10 +47,11 @@ type Node struct {
|
||||
}
|
||||
|
||||
type Core struct {
|
||||
Id int `json:"core_id"`
|
||||
Threads []int `json:"thread_ids"`
|
||||
Caches []Cache `json:"caches"`
|
||||
SocketID int `json:"socket_id"`
|
||||
Id int `json:"core_id"`
|
||||
Threads []int `json:"thread_ids"`
|
||||
Caches []Cache `json:"caches"`
|
||||
UncoreCaches []Cache `json:"uncore_caches"`
|
||||
SocketID int `json:"socket_id"`
|
||||
}
|
||||
|
||||
type Cache struct {
|
||||
|
||||
@@ -298,7 +298,7 @@ func TestTopologyWithoutNodes(t *testing.T) {
|
||||
topologyJSON2, err := json.Marshal(topology[1])
|
||||
assert.Nil(t, err)
|
||||
|
||||
expectedTopology1 := `{"node_id":0,"memory":0,"hugepages":null,"cores":[{"core_id":0,"thread_ids":[0,2],"caches":[{"id":0, "size":32768,"type":"unified","level":0}], "socket_id": 0}],"caches":null}`
|
||||
expectedTopology1 := `{"node_id":0,"memory":0,"hugepages":null,"cores":[{"core_id":0,"thread_ids":[0,2],"caches":[{"id":0, "size":32768,"type":"unified","level":0}], "socket_id": 0, "uncore_caches":null}],"caches":null}`
|
||||
expectedTopology2 := `
|
||||
{
|
||||
"node_id":1,
|
||||
@@ -319,7 +319,8 @@ func TestTopologyWithoutNodes(t *testing.T) {
|
||||
"level":0
|
||||
}
|
||||
],
|
||||
"socket_id": 1
|
||||
"socket_id": 1,
|
||||
"uncore_caches": null
|
||||
}
|
||||
],
|
||||
"caches":null
|
||||
|
||||
@@ -334,6 +334,14 @@ func getCaches(machineInfo *info.MachineInfo) metricValues {
|
||||
timestamp: machineInfo.Timestamp,
|
||||
})
|
||||
}
|
||||
for _, cache := range core.UncoreCaches {
|
||||
mValues = append(mValues,
|
||||
metricValue{
|
||||
value: float64(cache.Size),
|
||||
labels: []string{nodeID, coreID, cache.Type, strconv.Itoa(cache.Level)},
|
||||
timestamp: machineInfo.Timestamp,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for _, cache := range node.Caches {
|
||||
|
||||
@@ -337,16 +337,29 @@ func addCacheInfo(sysFs sysfs.SysFs, node *info.Node) error {
|
||||
Level: cache.Level,
|
||||
Type: cache.Type,
|
||||
}
|
||||
if cache.Cpus == numThreadsPerNode && cache.Level > cacheLevel2 {
|
||||
// Add a node-level cache.
|
||||
cacheFound := false
|
||||
for _, nodeCache := range node.Caches {
|
||||
if nodeCache == c {
|
||||
cacheFound = true
|
||||
if cache.Level > cacheLevel2 {
|
||||
if cache.Cpus == numThreadsPerNode {
|
||||
// Add a node level cache.
|
||||
cacheFound := false
|
||||
for _, nodeCache := range node.Caches {
|
||||
if nodeCache == c {
|
||||
cacheFound = true
|
||||
}
|
||||
}
|
||||
if !cacheFound {
|
||||
node.Caches = append(node.Caches, c)
|
||||
}
|
||||
} else {
|
||||
// Add uncore cache, for architecture in which l3 cache only shared among some cores.
|
||||
uncoreCacheFound := false
|
||||
for _, uncoreCache := range node.Cores[coreID].UncoreCaches {
|
||||
if uncoreCache == c {
|
||||
uncoreCacheFound = true
|
||||
}
|
||||
}
|
||||
if !uncoreCacheFound {
|
||||
node.Cores[coreID].UncoreCaches = append(node.Cores[coreID].UncoreCaches, c)
|
||||
}
|
||||
}
|
||||
if !cacheFound {
|
||||
node.Caches = append(node.Caches, c)
|
||||
}
|
||||
} else if cache.Cpus == numThreadsPerCore {
|
||||
// Add core level cache
|
||||
|
||||
@@ -179,7 +179,8 @@ func TestGetNodesInfo(t *testing.T) {
|
||||
1
|
||||
],
|
||||
"caches": null,
|
||||
"socket_id": 0
|
||||
"uncore_caches": null,
|
||||
"socket_id": 0
|
||||
}
|
||||
],
|
||||
"caches": [
|
||||
@@ -208,7 +209,8 @@ func TestGetNodesInfo(t *testing.T) {
|
||||
3
|
||||
],
|
||||
"caches": null,
|
||||
"socket_id": 1
|
||||
"uncore_caches": null,
|
||||
"socket_id": 1
|
||||
}
|
||||
],
|
||||
"caches": [
|
||||
@@ -287,7 +289,8 @@ func TestGetNodesInfo(t *testing.T) {
|
||||
1
|
||||
],
|
||||
"caches": null,
|
||||
"socket_id": 0
|
||||
"socket_id": 0,
|
||||
"uncore_caches": null
|
||||
},
|
||||
{
|
||||
"core_id": 1,
|
||||
@@ -296,7 +299,8 @@ func TestGetNodesInfo(t *testing.T) {
|
||||
3
|
||||
],
|
||||
"caches": null,
|
||||
"socket_id": 1
|
||||
"socket_id": 1,
|
||||
"uncore_caches": null
|
||||
},
|
||||
{
|
||||
"core_id": 2,
|
||||
@@ -305,7 +309,8 @@ func TestGetNodesInfo(t *testing.T) {
|
||||
5
|
||||
],
|
||||
"caches": null,
|
||||
"socket_id": 2
|
||||
"socket_id": 2,
|
||||
"uncore_caches": null
|
||||
}
|
||||
],
|
||||
"caches": [
|
||||
@@ -431,7 +436,8 @@ func TestGetNodesInfoWithOfflineCPUs(t *testing.T) {
|
||||
0
|
||||
],
|
||||
"caches": null,
|
||||
"socket_id": 0
|
||||
"socket_id": 0,
|
||||
"uncore_caches": null
|
||||
}
|
||||
],
|
||||
"caches": [
|
||||
@@ -459,7 +465,8 @@ func TestGetNodesInfoWithOfflineCPUs(t *testing.T) {
|
||||
2
|
||||
],
|
||||
"caches": null,
|
||||
"socket_id": 1
|
||||
"socket_id": 1,
|
||||
"uncore_caches": null
|
||||
}
|
||||
],
|
||||
"caches": [
|
||||
@@ -606,7 +613,8 @@ func TestGetNodesInfoWithoutCacheInfo(t *testing.T) {
|
||||
1
|
||||
],
|
||||
"caches": null,
|
||||
"socket_id": 0
|
||||
"uncore_caches": null,
|
||||
"socket_id": 0
|
||||
}
|
||||
],
|
||||
"caches": null
|
||||
@@ -628,7 +636,8 @@ func TestGetNodesInfoWithoutCacheInfo(t *testing.T) {
|
||||
3
|
||||
],
|
||||
"caches": null,
|
||||
"socket_id": 1
|
||||
"uncore_caches": null,
|
||||
"socket_id": 1
|
||||
}
|
||||
],
|
||||
"caches": null
|
||||
@@ -713,7 +722,8 @@ func TestGetNodesInfoWithoutHugePagesInfo(t *testing.T) {
|
||||
"level": 2
|
||||
}
|
||||
],
|
||||
"socket_id": 0
|
||||
"uncore_caches": null,
|
||||
"socket_id": 0
|
||||
}
|
||||
],
|
||||
"caches": null
|
||||
@@ -737,7 +747,8 @@ func TestGetNodesInfoWithoutHugePagesInfo(t *testing.T) {
|
||||
"level": 2
|
||||
}
|
||||
],
|
||||
"socket_id": 1
|
||||
"uncore_caches": null,
|
||||
"socket_id": 1
|
||||
}
|
||||
],
|
||||
"caches": null
|
||||
@@ -819,7 +830,8 @@ func TestGetNodesInfoWithoutNodes(t *testing.T) {
|
||||
"level":1
|
||||
}
|
||||
],
|
||||
"socket_id": 0
|
||||
"socket_id": 0,
|
||||
"uncore_caches": null
|
||||
}
|
||||
],
|
||||
"caches":null
|
||||
@@ -843,6 +855,7 @@ func TestGetNodesInfoWithoutNodes(t *testing.T) {
|
||||
"level":1
|
||||
}
|
||||
],
|
||||
"uncore_caches": null,
|
||||
"socket_id": 1
|
||||
}
|
||||
],
|
||||
@@ -914,7 +927,8 @@ func TestGetNodesInfoWithoutNodesWhenPhysicalPackageIDMissingForOneCPU(t *testin
|
||||
0
|
||||
],
|
||||
"caches": null,
|
||||
"socket_id": 0
|
||||
"socket_id": 0,
|
||||
"uncore_caches": null
|
||||
}
|
||||
],
|
||||
"caches":null
|
||||
@@ -1052,7 +1066,8 @@ func TestGetNodesWhenTopologyDirMissingForOneCPU(t *testing.T) {
|
||||
0
|
||||
],
|
||||
"caches":null,
|
||||
"socket_id":0
|
||||
"socket_id":0,
|
||||
"uncore_caches":null
|
||||
}
|
||||
],
|
||||
"caches": null
|
||||
@@ -1143,7 +1158,8 @@ func TestGetNodesWhenPhysicalPackageIDMissingForOneCPU(t *testing.T) {
|
||||
0
|
||||
],
|
||||
"caches":null,
|
||||
"socket_id":0
|
||||
"socket_id":0,
|
||||
"uncore_caches": null
|
||||
}
|
||||
],
|
||||
"caches": null
|
||||
@@ -1455,3 +1471,113 @@ func TestGetOnlineCPUs(t *testing.T) {
|
||||
onlineCPUs := GetOnlineCPUs(topology)
|
||||
assert.Equal(t, onlineCPUs, []int{0, 1, 2, 3, 4, 5, 6, 7})
|
||||
}
|
||||
|
||||
func TestGetNodesInfoWithUncoreCacheInfo(t *testing.T) {
|
||||
fakeSys := &fakesysfs.FakeSysFs{}
|
||||
c := sysfs.CacheInfo{
|
||||
Id: 0,
|
||||
Size: 32 * 1024,
|
||||
Type: "unified",
|
||||
Level: 3,
|
||||
Cpus: 8,
|
||||
}
|
||||
fakeSys.SetCacheInfo(c)
|
||||
|
||||
nodesPaths := []string{
|
||||
"/fakeSysfs/devices/system/node/node0",
|
||||
"/fakeSysfs/devices/system/node/node1",
|
||||
}
|
||||
fakeSys.SetNodesPaths(nodesPaths, nil)
|
||||
|
||||
memTotal := "MemTotal: 32817192 kB"
|
||||
fakeSys.SetMemory(memTotal, nil)
|
||||
|
||||
cpusPaths := map[string][]string{
|
||||
"/fakeSysfs/devices/system/node/node0": {
|
||||
"/fakeSysfs/devices/system/node/node0/cpu0",
|
||||
"/fakeSysfs/devices/system/node/node0/cpu1",
|
||||
},
|
||||
"/fakeSysfs/devices/system/node/node1": {
|
||||
"/fakeSysfs/devices/system/node/node0/cpu2",
|
||||
"/fakeSysfs/devices/system/node/node0/cpu3",
|
||||
},
|
||||
}
|
||||
fakeSys.SetCPUsPaths(cpusPaths, nil)
|
||||
|
||||
coreThread := map[string]string{
|
||||
"/fakeSysfs/devices/system/node/node0/cpu0": "0",
|
||||
"/fakeSysfs/devices/system/node/node0/cpu1": "0",
|
||||
"/fakeSysfs/devices/system/node/node0/cpu2": "1",
|
||||
"/fakeSysfs/devices/system/node/node0/cpu3": "1",
|
||||
}
|
||||
fakeSys.SetCoreThreads(coreThread, nil)
|
||||
physicalPackageIDs := map[string]string{
|
||||
"/fakeSysfs/devices/system/node/node0/cpu0": "0",
|
||||
"/fakeSysfs/devices/system/node/node0/cpu1": "0",
|
||||
"/fakeSysfs/devices/system/node/node0/cpu2": "1",
|
||||
"/fakeSysfs/devices/system/node/node0/cpu3": "1",
|
||||
}
|
||||
fakeSys.SetPhysicalPackageIDs(physicalPackageIDs, nil)
|
||||
|
||||
nodes, cores, err := GetNodesInfo(fakeSys)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, len(nodes))
|
||||
assert.Equal(t, 4, cores)
|
||||
|
||||
nodesJSON, err := json.Marshal(nodes)
|
||||
assert.Nil(t, err)
|
||||
expectedNodes := `
|
||||
[
|
||||
{
|
||||
"node_id": 0,
|
||||
"memory": 33604804608,
|
||||
"hugepages": null,
|
||||
"cores": [
|
||||
{
|
||||
"core_id": 0,
|
||||
"thread_ids": [
|
||||
0,
|
||||
1
|
||||
],
|
||||
"caches": null,
|
||||
"uncore_caches": [
|
||||
{
|
||||
"id": 0,
|
||||
"size": 32768,
|
||||
"type": "unified",
|
||||
"level": 3
|
||||
}
|
||||
],
|
||||
"socket_id": 0
|
||||
}
|
||||
],
|
||||
"caches": null
|
||||
},
|
||||
{
|
||||
"node_id": 1,
|
||||
"memory": 33604804608,
|
||||
"hugepages": null,
|
||||
"cores": [
|
||||
{
|
||||
"core_id": 1,
|
||||
"thread_ids": [
|
||||
2,
|
||||
3
|
||||
],
|
||||
"caches": null,
|
||||
"uncore_caches": [
|
||||
{
|
||||
"id": 0,
|
||||
"size": 32768,
|
||||
"type": "unified",
|
||||
"level": 3
|
||||
}
|
||||
],
|
||||
"socket_id": 1
|
||||
}
|
||||
],
|
||||
"caches": null
|
||||
}
|
||||
]`
|
||||
assert.JSONEq(t, expectedNodes, string(nodesJSON))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user