Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 24 additions & 13 deletions cmd/metrics/event_frame.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,26 +219,37 @@ func coalesceEvents(allEvents []Event, scope string, granularity string, metadat
// create a mapping of cpu numbers to event indices
var cpuMap map[int]int

// if cpu range is specified, use it to determine the number of cpus
// otherwise, use the number of sockets, cores per socket, and threads per core
// to determine the number of cpus
// create a list of CPU IDs targeted for profiling
var cpuIDs []int

// if CPU range is specified, use it to determine the number of CPUs
// otherwise, use the CPUSocketMap structure to determine the online CPUs
// then create a list of CPU IDs for the targeted CPUs
if flagCpuRange != "" {
cpuList, err := util.SelectiveIntRangeToIntList(flagCpuRange)
var err error
cpuIDs, err = util.SelectiveIntRangeToIntList(flagCpuRange)
if err != nil {
return nil, fmt.Errorf("failed to parse cpu range: %w", err)
}
numCPUs = len(cpuList)
cpuMap = make(map[int]int, numCPUs)
for i, cpu := range cpuList {
cpuMap[cpu] = i
}
numCPUs = len(cpuIDs)
} else {
numCPUs = metadata.SocketCount * metadata.CoresPerSocket * metadata.ThreadsPerCore
cpuMap = make(map[int]int, numCPUs)
for i := 0; i < numCPUs; i++ {
cpuMap[i] = i
numCPUs = len(metadata.CPUSocketMap)

for cpuID := range metadata.CPUSocketMap {
cpuIDs = append(cpuIDs, cpuID)
}
}

// create a mapping of the target CPU IDs to their event indices
cpuMap = make(map[int]int, numCPUs)

// sort the CPU IDs
slices.Sort(cpuIDs)

// place the sorted CPU IDs into the mapping
for idx, cpuID := range cpuIDs {
cpuMap[cpuID] = idx
}
// note: if some cores have been off-lined, this may cause an issue because 'perf' seems
// to still report events for those cores
newEvents := make([][]Event, numCPUs)
Expand Down
29 changes: 9 additions & 20 deletions cmd/metrics/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func LoadMetadata(myTarget target.Target, noRoot bool, noSystemSummary bool, per
metadata.ThreadsPerCore = 1
}
// CPUSocketMap (from cpuInfo)
metadata.CPUSocketMap = createCPUSocketMap(metadata.CoresPerSocket, metadata.SocketCount, metadata.ThreadsPerCore == 2)
metadata.CPUSocketMap = createCPUSocketMap(cpuInfo)
// Model Name (from cpuInfo)
metadata.ModelName = cpuInfo[0]["model name"]
// Vendor (from cpuInfo)
Expand Down Expand Up @@ -709,29 +709,18 @@ func getKernelVersion(scriptOutputs map[string]script.ScriptOutput) (version str
}

// createCPUSocketMap creates a mapping of logical CPUs to their corresponding sockets.
// The function takes the number of cores per socket, the number of sockets, and a boolean indicating whether hyperthreading is enabled.
// The function traverses the output of /proc/cpuinfo and examines the "processor" and "physical id" fields.
// It returns a map where the key is the logical CPU index and the value is the socket index.
func createCPUSocketMap(coresPerSocket int, sockets int, hyperthreading bool) (cpuSocketMap map[int]int) {
func createCPUSocketMap(cpuInfo []map[string]string) (cpuSocketMap map[int]int) {
// Create an empty map
cpuSocketMap = make(map[int]int)

// Calculate the total number of logical CPUs
totalCPUs := coresPerSocket * sockets
if hyperthreading {
totalCPUs *= 2 // hyperthreading doubles the number of logical CPUs
}
// Assign each CPU to a socket
for i := range totalCPUs {
// Assume that the CPUs are evenly distributed between the sockets
socket := i / coresPerSocket
if hyperthreading {
// With non-adjacent hyperthreading, the second logical CPU of each core is in the second half
if i >= totalCPUs/2 {
socket = (i - totalCPUs/2) / coresPerSocket
}
}
// Store the mapping
cpuSocketMap[i] = socket
// Iterate over the CPU info to create the mapping
for idx := range cpuInfo {
procID, _ := strconv.Atoi(cpuInfo[idx]["processor"])
physID, _ := strconv.Atoi(cpuInfo[idx]["physical id"])
cpuSocketMap[procID] = physID
}

return cpuSocketMap
}