std/os/processor
std/os/src/processor.trb
Processor - how many processors the machine has, what they are and how busy they are - with ProcessorTimes, the
cumulative time each state has taken, ProcessorUsage, the fractions of an interval, ProcessorDescription, what a
processor says about itself, and Frequency, a processor clock.
Each question is a match OperatingSystem.current whose arm hands it to the directory of that system; only the arm
of the build's target is compiled. The sums and the fractions here are pure, so their tests run on every machine.
type Frequency
type Frequency with Show, Compare
A processor clock: a count of hertz.
Examples
print Frequency.ofMegahertz(3_600)
print Frequency.ofMegahertz(800).gigahertz()
Related
Processor- whose clocks it is.
fn ofHertz
static fn ofHertz(hertz: Int64): Frequency
A clock of exactly this many hertz.
fn ofMegahertz
static fn ofMegahertz(megahertz: Int64): Frequency
A clock of this many megahertz.
fn hertz
fn hertz(): Int64
As a whole number of hertz, which is exactly what it holds.
fn megahertz
fn megahertz(): Float64
In megahertz of a million hertz.
fn gigahertz
fn gigahertz(): Float64
In gigahertz of a thousand megahertz.
fn compare
fn compare(other: Self): Ordering
Which of the two clocks is the slower one.
fn show
fn show(): String
The unit that fits: whole megahertz below 1000 of them (800 MHz), gigahertz to one decimal from there on
(3.6 GHz), both rounded half up, and hertz below one megahertz (500 Hz).
type Processor
type Processor
The processors of this machine. logicalCount is the machine; what this process may use is
CurrentProcess.processors(), which honours the affinity mask and a container's CPU quota.
Examples
print "{Processor.logicalCount()?} threads on {Processor.physicalCount()?} cores"
const usage = Processor.usage(500.milliseconds()).await()?
print "{usage.busy * 100.0}% busy"
Related
ProcessorTimes- the cumulative timesusageis the difference of.
fn logicalCount
static fn logicalCount(): Result<Int, OsError>
How many logical processors the system runs threads on, hyper-threads included; at least one.
Errors
OsError.Unsupportedon FreeBSD, whose slice has not come yet, and in a browser, which cannot tell.OsError.Failedwhere the system's call fails, with its words.
fn physicalCount
static fn physicalCount(): Result<Int, OsError>
How many physical cores: never more than Processor.logicalCount. Where the system does not say - Arm Linux
writes no core identifiers - every logical processor counts as a core.
Errors
- The errors of
Processor.logicalCount.
fn describe
static fn describe(): Result<ProcessorDescription, OsError>
Vendor, model, packages, cores, caches and features of the processor, read once. On x86-64 it is assembled from what
cpuid says - the vendor, the brand string, the caches and the features the system lets a program use - and the
system's own counts of packages, cores and logical processors, because on a processor with cores of different
kinds cpuid answers for the core it happens to run on. The frequencies are None until they have a source.
Examples
const processor = Processor.describe().expect("the processor")
print "{processor.model}: {processor.physicalCores} cores, {processor.logicalProcessors} threads"
print processor.features.contains(ProcessorFeature.Avx2)
Errors
OsError.Unsupportedon FreeBSD and in a browser, and on an architecture other than x86-64, whose description has not come yet.- The errors of
Processor.logicalCountandProcessor.physicalCount. OsError.Failedwhere the system's call for the packages fails, with its words.
fn times
static fn times(): Result<ProcessorTimes, OsError>
The time every processor together has spent in each state since the system started. Two readings are monotonic,
and their difference is what Processor.usage reports.
Errors
OsError.Malformedwhere/proc/statis not in the form Linux writes it.OsError.Unsupportedon FreeBSD and in a browser.OsError.Failedwhere the system's call fails, with its words.
fn timesOfEach
static fn timesOfEach(): Result<List<ProcessorTimes>, OsError>
The same, for each logical processor, in the system's order: as many as Processor.logicalCount says.
Errors
- The errors of
Processor.times.
fn usage
static fn usage(interval: Duration = 1.seconds()): Task<Result<ProcessorUsage, OsError>>
How busy the processors were over interval: two readings of Processor.times and Processor.timesOfEach, and
a sleep between them.
Errors
- The errors of
Processor.times, from either reading.
type ProcessorTimes
type ProcessorTimes with Show, Equals, Subtract
Cumulative time in each state. The difference of two readings is what Processor.usage reports.
Pitfalls
- What a system counts differently stays in
other: Linux foldsnice, interrupts and stolen time into it, and Windows counts the interrupt and deferred-procedure time insidesystem, so itswaitingandotherare zero.
field user
user: Duration
Running programs of users.
field system
system: Duration
Running the system for them.
field idle
idle: Duration
With nothing to run.
field waiting
waiting: Duration
Waiting for input or output with nothing else to run: Linux iowait. Zero where the system does not count it.
field other
other: Duration
Everything else the system counts: nice, interrupts, stolen time.
fn total
fn total(): Duration
The five states together: the time the processors have existed.
fn subtract
fn subtract(other: Self): Self
These times less other, state by state.
type ProcessorUsage
type ProcessorUsage with Show, Equals
Fractions of an interval, each between 0 and 1.
Examples
const usage = Processor.usage().await()?
for fraction in usage.each {
print fraction
}
Related
Processor.usage- which reads them.
field busy
busy: Float64
user + system of all processors together, as a fraction of their total time.
field user
user: Float64
The share of the total time that ran programs of users.
field system
system: Float64
The share that ran the system.
field each
each: List<Float64>
busy of each processor, in the order of Processor.timesOfEach.
fn between
static fn between(total: ProcessorTimes, each: List<ProcessorTimes>): ProcessorUsage
The fractions of two differences of ProcessorTimes: all processors together, and each one. A difference that
covers no time at all - or a negative one, where a counter went backwards - answers 0, never NaN.
type ProcessorDescription
type ProcessorDescription with Show, Equals
What a processor says about itself, as Processor.describe reads it.
Examples
const processor = Processor.describe().expect("the processor")
print processor.vendor
print processor.model
for cache in processor.caches {
print "L{cache.level} {cache.kind}: {cache.size}"
}
Pitfalls
physicalCoresandlogicalProcessorsare the machine's, as the system counts them, and not whatcpuidsays of the one core it ran on: they differ on a processor with cores of different kinds.cachesandfeaturesare those of the core that answered, which on such a processor is one of several kinds.
Related
Processor.describe- which reads it.ProcessorCache,ProcessorFeature- whatcachesandfeatureshold.
field vendor
vendor: String
The vendor string: GenuineIntel, AuthenticAMD.
field model
model: String
The brand string, AMD Ryzen 9 7950X 16-Core Processor; the vendor string where the processor has none.
field packages
packages: Int
How many processors (sockets) the machine has; at least one.
field physicalCores
physicalCores: Int
The cores of all packages together, as the system counts them.
field logicalProcessors
logicalProcessors: Int
The logical processors of all packages together, hyper-threads included.
field baseFrequency
baseFrequency: Frequency?
The clock the processor is rated at; None until a source for it exists.
field maximumFrequency
maximumFrequency: Frequency?
The highest clock the processor reaches; None until a source for it exists.
field caches
caches: List<ProcessorCache>
The caches the processor lists, level by level; empty where it lists none.
field features
features: Set<ProcessorFeature>
The extensions a program may use.
type ProcessorCache
type ProcessorCache with Show, Equals
One cache of a processor, as the processor describes it: the level, what it holds, how large it is and how long its lines are. A cache that several cores share is one entry, with its full size.
Examples
fn describe(caches: List<ProcessorCache>) {
for cache in caches {
print "L{cache.level} {cache.kind}: {cache.size}"
}
}
Related
ProcessorFeature- what the instruction set of the same processor offers.
type ProcessorFeature
type ProcessorFeature with Show, Equals, Hash
An instruction-set extension a program may dispatch on, named after the extension as its vendor spells it. The list is closed and grows with its users: a case is added when something reads it.
On x86-64 a feature is reported only when the processor has it and the operating system can use it: the AVX family needs the system to save the wider registers on a task switch, which a processor's own bit does not say.
Examples
fn wideKernelsAreSafe(features: Set<ProcessorFeature>): Bool {
features.contains ProcessorFeature.Avx2
}
Related
ProcessorCache- the caches of the same processor.
case Sse2
case Sse2
SSE2, which every x86-64 processor has.
case Sse3
case Sse3
SSE3.
case Ssse3
case Ssse3
Supplemental SSE3.
case Sse41
case Sse41
SSE4.1.
case Sse42
case Sse42
SSE4.2.
case Avx
case Avx
AVX, with the system saving the 256-bit registers.
case Avx2
case Avx2
AVX2, with the system saving the 256-bit registers.
case Fma
case Fma
Fused multiply-add on the AVX registers.
case Bmi1
case Bmi1
The first bit-manipulation set.
case Bmi2
case Bmi2
The second bit-manipulation set.
case Avx512Foundation
case Avx512Foundation
AVX-512 Foundation, with the system saving the 512-bit registers and the mask registers.
case Aes
case Aes
The AES instructions.
case Sha
case Sha
The SHA-1 and SHA-256 instructions.
case Neon
case Neon
Arm Advanced SIMD.
case Crc32
case Crc32
The Arm CRC32 instructions.
case DotProduct
case DotProduct
The Arm dot-product instructions.
case Sve
case Sve
The Arm Scalable Vector Extension.
case Sve2
case Sve2
The second version of the Arm Scalable Vector Extension.