1
0
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:
ranchochen
2021-04-14 22:18:44 +08:00
committed by Paweł Szulik
parent 13351bf548
commit 505190f40b
5 changed files with 179 additions and 30 deletions

View File

@@ -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 {

View File

@@ -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

View File

@@ -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 {

View File

@@ -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

View File

@@ -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))
}