The kernel numbers the whole machine's threads in one run and deals them out a socket at a time, twice: nexus's first CPU listed C0–C9 and C20–C29, its second C10–C19 and C30–C39. Each CPU now lists its own twenty as C0–C19; the kernel's number is in the row's tooltip. Co-Authored-By: Claude <noreply@anthropic.com>
18 lines
1.2 KiB
TypeScript
18 lines
1.2 KiB
TypeScript
// Which threads belong to which CPU, on a machine with more than one.
|
||
//
|
||
// The kernel numbers every thread of the machine in one run, and on a two-socket board with
|
||
// hyper-threading it deals them out a socket at a time and then goes round again: cpu 0–9 are
|
||
// CPU 1's cores, 10–19 CPU 2's, 20–29 the second threads of CPU 1's, 30–39 of CPU 2's. Listed
|
||
// under its CPU by that number, a 20-thread processor reads "C0…C9, C20…C29" and the one
|
||
// beside it "C10…C19, C30…C39" — neither looks like twenty of anything. So each CPU's threads
|
||
// are counted from 0 under it, in the kernel's order, the way a one-socket machine's are: the
|
||
// first half are its cores, the second half their second threads.
|
||
//
|
||
// `pkgs[i]` is the socket logical CPU `i` is on. The answer is, for each socket (ascending),
|
||
// the logical CPUs on it (ascending); a thread's number under its CPU is its place in that list.
|
||
export function socketThreads(pkgs: number[]): { pkg: number; cpus: number[] }[] {
|
||
const by = new Map<number, number[]>()
|
||
pkgs.forEach((pk, i) => { const l = by.get(pk); if (l) l.push(i); else by.set(pk, [i]) })
|
||
return [...by.entries()].sort((a, b) => a[0] - b[0]).map(([pkg, cpus]) => ({ pkg, cpus }))
|
||
}
|