counting-group.dhover×253all
#!/usr/bin/env dub
/+ dub.sdl:
    name "cpu_pmu_counting_group"
    platforms "linux"
    targetPath "build"
+/
/**
 * Grouped scalar counting via `perf_event_open(2)` and PMC multiplexing, pure D.
 *
 * Two demonstrations of the Linux *counting* path, both over druntime's
 * `core.sys.linux.perf_event` (the attr layout + syscall wrapper) — no C shim:
 *
 *   1. A `PERF_FORMAT_GROUP` group — a `cycles` leader plus `instructions` —
 *      read in one `read(2)` as `{nr, time_enabled, time_running, value[nr]}`.
 *      The two values give IPC. Because the events share one group the kernel
 *      schedules them as a unit, so `time_running == time_enabled` and the
 *      counts are exact (`scale == 1.0`).
 *   2. Deliberate oversubscription: N independent single-event groups (N greater
 *      than the PMU's general-purpose counters — 6 on Zen 4) opened over one
 *      workload window so the kernel round-robin-*multiplexes* them. Each event
 *      then reports `time_running < time_enabled`; perf recovers an estimate by
 *      scaling `raw * time_enabled / time_running`. This is the accuracy cost
 *      the grouped path in (1) is designed to avoid.
 *
 * Companion to docs/research/cpu-pmu/linux-perf-events.md
 *   § "Scalar counting: groups, `PERF_FORMAT_GROUP`, and multiplexing".
 *
 * Run with: dub run --single counting-group.d
 *
 * Environment recorded: Linux 6.18.26, AMD Ryzen 9 7940HX (Zen 4; 6 core PMCs),
 * `/proc/sys/kernel/perf_event_paranoid` = -1, LDC 1.41 druntime
 * `core.sys.linux.perf_event`.
 *
 * Portability: any `perf_event_open` failure (`perf_event_paranoid`, seccomp,
 * no PMU, non-Linux) prints a `SKIP:` line and exits 0 so CI stays green on any
 * host.
 */
module 
(module) cpu_pmu_counting_group

Grouped scalar counting via perf_event_open(2) and PMC multiplexing, pure D.

Two demonstrations of the Linux counting path, both over druntime's core.sys.linux.perf_event (the attr layout + syscall wrapper) — no C shim:

  1. A PERF_FORMAT_GROUP group — a cycles leader plus instructions — read in one read(2) as {nr, time_enabled, time_running, value[nr]}. The two values give IPC. Because the events share one group the kernel schedules them as a unit, so time_running == time_enabled and the counts are exact (scale == 1.0).

  2. Deliberate oversubscription: N independent single-event groups (N greater than the PMU's general-purpose counters — 6 on Zen 4) opened over one workload window so the kernel round-robin-multiplexes them. Each event then reports time_running < time_enabled; perf recovers an estimate by scaling raw * time_enabled / time_running. This is the accuracy cost the grouped path in (1) is designed to avoid.

Companion to docs/research/cpu-pmu/linux-perf-events.md § "Scalar counting: groups, PERF_FORMAT_GROUP, and multiplexing".

Run with: dub run --single counting-group.d

Environment recorded: Linux 6.18.26, AMD Ryzen 9 7940HX (Zen 4; 6 core PMCs), /proc/sys/kernel/perf_event_paranoid = -1, LDC 1.41 druntime core.sys.linux.perf_event.

Portability

any perf_event_open failure (perf_event_paranoid, seccomp, no PMU, non-Linux) prints a SKIP: line and exits 0 so CI stays green on any host.

cpu_pmu_counting_group
;
version (
linux
linux
)
{ import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.linux
linux
.
(module) core.sys.linux.perf_event

D header file for perf_event_open system call.

Converted from linux userspace header, comments included.

@authorsMax Haughton
perf_event
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(module) core.sys.posix.unistd

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly@standardsThe Open Group Base Specifications Issue 8, IEEE Std 1003.1, 2024 Edition
unistd
:
(alias) cpu_pmu_counting_group.read = long core.sys.posix.unistd.read(int, void*, ulong) nothrow @nogc
read
,
(alias) cpu_pmu_counting_group.close = int core.sys.posix.unistd.close(int) nothrow @nogc @trusted
close
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(package) core.sys.posix.sys
sys
.
(module) core.sys.posix.sys.ioctl

D header file for POSIX.

@copyrightCopyright Alex Rønne Petersen 2011 - 2012.@licenseBoost License 1.0.@authorsAlex Rønne Petersen@standardsThe Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
ioctl
:
(alias) cpu_pmu_counting_group.ioctl = int core.sys.posix.sys.ioctl.ioctl(int __fd, ulong __request, ...) nothrow @nogc
ioctl
;
import
(package) core
core
.
(package) core.stdc
stdc
.
(module) core.stdc.config

D compatible types that correspond to various basic types in associated C and C++ compilers.

Source

core/stdc/config.d

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseDistributed under the Boost Software License 1.0. (See accompanying file LICENSE)@authorsSean Kelly@standardsISO/IEC 9899:1999 (E)
config
: c_ulong;
import
(package) std
std
.
(module) std.stdio
Category Symbols
File handles _popen File isFileHandle openNetwork stderr stdin stdout
Reading chunks lines readf readfln readln
Writing toFile write writef writefln writeln
Misc KeepTerminator LockType StdioException

Standard I/O functions that extend core.stdc.stdio. core.stdc.stdio is publically imported when importing std.stdio.

There are three layers of I/O:

  1. The lowest layer is the operating system layer. The two main schemes are Windows and Posix.

  2. C's stdio.h which unifies the two operating system schemes.

  3. std.stdio, this module, unifies the various stdio.h implementations into a high level package for D programs.

Source

std/stdio.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Alex Rønne Petersen
stdio
:
(alias template) cpu_pmu_counting_group.writefln = std.stdio.writefln(alias fmt, A...)(A args) if (isSomeString!(typeof(fmt)))

Equivalent to writef(fmt, args, '\n').

writefln
,
(alias template) cpu_pmu_counting_group.writeln = std.stdio.writeln(T...)(T args)

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
;
/// A hardware event to count, named for the report. struct
(struct) cpu_pmu_counting_group.Ev

A hardware event to count, named for the report.

Ev
{
(alias) object.string = string
string
(field) string cpu_pmu_counting_group.Ev.name
name
;
ulong
(field) ulong cpu_pmu_counting_group.Ev.config
config
; // a `perf_hw_id`
} /// Opens one `PERF_TYPE_HARDWARE` event on the calling thread (`pid == 0`), /// any CPU (`cpu == -1`). `groupFd == -1` makes it a group leader; a leader /// carries the read format (`PERF_FORMAT_GROUP` when `grouped`, plus the two /// time fields) and starts `disabled`. Returns the fd, or -1 on failure. int
int cpu_pmu_counting_group.openEvent(ulong config, int groupFd, bool grouped, bool excludeKernel) @trusted

Opens one PERF_TYPE_HARDWARE event on the calling thread (pid == 0), any CPU (cpu == -1). groupFd` == -1` makes it a group leader; a leader carries the read format (`PERF_FORMAT_GROUP` when grouped``, plus the two time fields) and starts disabled. Returns the fd, or -1 on failure.

openEvent
(ulong
(parameter) ulong config
config
, int
(parameter) int groupFd
groupFd
, bool
(parameter) bool grouped
grouped
, bool
(parameter) bool excludeKernel
excludeKernel
) @trusted
{
(struct) core.sys.linux.perf_event.perf_event_attr

Hardware event_id to monitor via a performance monitoring event:

@sample_max_stack: Max number of frame pointers in a callchain, should be < /proc/sys/kernel/perf_event_max_stack

perf_event_attr
(local variable) core.sys.linux.perf_event.perf_event_attr attr
attr
;
(local variable) core.sys.linux.perf_event.perf_event_attr attr
attr
.
(field) uint core.sys.linux.perf_event.perf_event_attr.size

Size of the attr structure, for fwd/bwd compat.

size
=
(struct) core.sys.linux.perf_event.perf_event_attr

Hardware event_id to monitor via a performance monitoring event:

@sample_max_stack: Max number of frame pointers in a callchain, should be < /proc/sys/kernel/perf_event_max_stack

perf_event_attr
.
(constant) ulong core.sys.linux.perf_event.perf_event_attr.sizeof = 112LU
sizeof
;
(local variable) core.sys.linux.perf_event.perf_event_attr attr
attr
.
(field) uint core.sys.linux.perf_event.perf_event_attr.type

Major type: hardware/software/tracepoint/etc.

type
=
(enum) core.sys.linux.perf_event.perf_type_id

attr.type

perf_type_id
.
(enum value) core.sys.linux.perf_event.perf_type_id.PERF_TYPE_HARDWARE = 0
PERF_TYPE_HARDWARE
;
(local variable) core.sys.linux.perf_event.perf_event_attr attr
attr
.
(field) ulong core.sys.linux.perf_event.perf_event_attr.config

Type specific configuration information.

config
=
(parameter) ulong config
config
;
(local variable) core.sys.linux.perf_event.perf_event_attr attr
attr
.
void core.sys.linux.perf_event.perf_event_attr.exclude_hv(ulong v) pure nothrow @nogc @property @safe
exclude_hv
= 1;
(local variable) core.sys.linux.perf_event.perf_event_attr attr
attr
.
void core.sys.linux.perf_event.perf_event_attr.exclude_kernel(ulong v) pure nothrow @nogc @property @safe
exclude_kernel
=
(parameter) bool excludeKernel
excludeKernel
? 1 : 0;
const
(local variable) const(bool) isLeader
isLeader
=
(parameter) int groupFd
groupFd
< 0;
(local variable) core.sys.linux.perf_event.perf_event_attr attr
attr
.
void core.sys.linux.perf_event.perf_event_attr.disabled(ulong v) pure nothrow @nogc @property @safe
disabled
=
(local variable) const(bool) isLeader
isLeader
? 1 : 0; // enabling the leader enables the group
if (
(local variable) const(bool) isLeader
isLeader
)
{
(local variable) core.sys.linux.perf_event.perf_event_attr attr
attr
.
(field) ulong core.sys.linux.perf_event.perf_event_attr.read_format
read_format
=
(enum) core.sys.linux.perf_event.perf_event_read_format

The format of the data returned by read() on a perf event fd, as specified by attr.read_format:

struct read_format {
   { u64        value;
     { u64        time_enabled; } && PERF_FORMAT_TOTAL_TIME_ENABLED
     { u64        time_running; } && PERF_FORMAT_TOTAL_TIME_RUNNING
     { u64        id;           } && PERF_FORMAT_ID
   } && !PERF_FORMAT_GROUP

   { u64        nr;
     { u64        time_enabled; } && PERF_FORMAT_TOTAL_TIME_ENABLED
     { u64        time_running; } && PERF_FORMAT_TOTAL_TIME_RUNNING
     { u64        value;
       { u64    id;           } && PERF_FORMAT_ID
     }        cntr[nr];
   } && PERF_FORMAT_GROUP
};
perf_event_read_format
.
(enum value) core.sys.linux.perf_event.perf_event_read_format.PERF_FORMAT_TOTAL_TIME_ENABLED = 1u
PERF_FORMAT_TOTAL_TIME_ENABLED
|
(enum) core.sys.linux.perf_event.perf_event_read_format

The format of the data returned by read() on a perf event fd, as specified by attr.read_format:

struct read_format {
   { u64        value;
     { u64        time_enabled; } && PERF_FORMAT_TOTAL_TIME_ENABLED
     { u64        time_running; } && PERF_FORMAT_TOTAL_TIME_RUNNING
     { u64        id;           } && PERF_FORMAT_ID
   } && !PERF_FORMAT_GROUP

   { u64        nr;
     { u64        time_enabled; } && PERF_FORMAT_TOTAL_TIME_ENABLED
     { u64        time_running; } && PERF_FORMAT_TOTAL_TIME_RUNNING
     { u64        value;
       { u64    id;           } && PERF_FORMAT_ID
     }        cntr[nr];
   } && PERF_FORMAT_GROUP
};
perf_event_read_format
.
(enum value) core.sys.linux.perf_event.perf_event_read_format.PERF_FORMAT_TOTAL_TIME_RUNNING = 2u
PERF_FORMAT_TOTAL_TIME_RUNNING
;
if (
(parameter) bool grouped
grouped
)
(local variable) core.sys.linux.perf_event.perf_event_attr attr
attr
.
(field) ulong core.sys.linux.perf_event.perf_event_attr.read_format
read_format
|=
(enum) core.sys.linux.perf_event.perf_event_read_format

The format of the data returned by read() on a perf event fd, as specified by attr.read_format:

struct read_format {
   { u64        value;
     { u64        time_enabled; } && PERF_FORMAT_TOTAL_TIME_ENABLED
     { u64        time_running; } && PERF_FORMAT_TOTAL_TIME_RUNNING
     { u64        id;           } && PERF_FORMAT_ID
   } && !PERF_FORMAT_GROUP

   { u64        nr;
     { u64        time_enabled; } && PERF_FORMAT_TOTAL_TIME_ENABLED
     { u64        time_running; } && PERF_FORMAT_TOTAL_TIME_RUNNING
     { u64        value;
       { u64    id;           } && PERF_FORMAT_ID
     }        cntr[nr];
   } && PERF_FORMAT_GROUP
};
perf_event_read_format
.
(enum value) core.sys.linux.perf_event.perf_event_read_format.PERF_FORMAT_GROUP = 8u
PERF_FORMAT_GROUP
;
} return cast(int)
long core.sys.linux.perf_event.perf_event_open(core.sys.linux.perf_event.perf_event_attr* hw_event, int pid, int cpu, int group_fd, ulong flags) nothrow @nogc
perf_event_open
(&
(local variable) core.sys.linux.perf_event.perf_event_attr attr
attr
, 0, -1,
(parameter) int groupFd
groupFd
, 0);
} void
void cpu_pmu_counting_group.ctl(int fd, uint request, bool wholeGroup) @trusted
ctl
(int
(parameter) int fd
fd
, uint
(parameter) uint request
request
, bool
(parameter) bool wholeGroup
wholeGroup
) @trusted
{
int core.sys.posix.sys.ioctl.ioctl(int __fd, ulong __request, ...) nothrow @nogc
ioctl
(
(parameter) int fd
fd
, cast(c_ulong)
(parameter) uint request
request
,
(parameter) bool wholeGroup
wholeGroup
?
(enum) core.sys.linux.perf_event.perf_event_ioc_flags
perf_event_ioc_flags
.
(enum value) core.sys.linux.perf_event.perf_event_ioc_flags.PERF_IOC_FLAG_GROUP = 1u
PERF_IOC_FLAG_GROUP
: 0);
} long
long cpu_pmu_counting_group.readN(int fd, ulong[] buf) @trusted
readN
(int
(parameter) int fd
fd
, ulong[]
(parameter) ulong[] buf
buf
) @trusted =>
long core.sys.posix.unistd.read(int, void*, ulong) nothrow @nogc
read
(
(parameter) int fd
fd
,
(parameter) ulong[] buf
buf
.
(field) ulong* ulong[].ptr
ptr
,
(parameter) ulong[] buf
buf
.
(field) ulong ulong[].length
length
* ulong.
(constant) ulong ulong.sizeof = 8LU
sizeof
);
/// A fixed amount of work: multiply-shift-xor mixing, enough retired /// instructions that counter noise is negligible. `__gshared` sink defeats /// dead-code elimination. __gshared ulong
(__gshared global) ulong cpu_pmu_counting_group.sink

A fixed amount of work: multiply-shift-xor mixing, enough retired instructions that counter noise is negligible. __gshared sink defeats dead-code elimination.

sink
;
void
void cpu_pmu_counting_group.workload()
workload
()
{ ulong
(local variable) ulong acc
acc
= 0x9E3779B97F4A7C15UL;
foreach (
(local variable) ulong i
i
; 0 .. 3_000_000UL)
(local variable) ulong acc
acc
= (
(local variable) ulong acc
acc
+
(local variable) ulong i
i
) * 2654435761UL ^ (
(local variable) ulong acc
acc
>> 13);
(__gshared global) ulong cpu_pmu_counting_group.sink

A fixed amount of work: multiply-shift-xor mixing, enough retired instructions that counter noise is negligible. __gshared sink defeats dead-code elimination.

sink
+=
(local variable) ulong acc
acc
;
} int
int cpu_pmu_counting_group.run()
run
()
{ // ---- Demo 1: a fitting group → exact IPC, scale == 1 -------------- // Probe permission once: prefer kernel+user, fall back to user-only. bool
(local variable) bool excludeKernel
excludeKernel
= false;
int
(local variable) int leader
leader
=
int cpu_pmu_counting_group.openEvent(ulong config, int groupFd, bool grouped, bool excludeKernel) @trusted

Opens one PERF_TYPE_HARDWARE event on the calling thread (pid == 0), any CPU (cpu == -1). groupFd` == -1` makes it a group leader; a leader carries the read format (`PERF_FORMAT_GROUP` when grouped``, plus the two time fields) and starts disabled. Returns the fd, or -1 on failure.

openEvent
(
(enum) core.sys.linux.perf_event.perf_hw_id

Generalized performance event event_id types, used by the attr.event_id parameter of the sys_perf_event_open() syscall:

perf_hw_id
.
(enum value) core.sys.linux.perf_event.perf_hw_id.PERF_COUNT_HW_CPU_CYCLES = 0
PERF_COUNT_HW_CPU_CYCLES
, -1, true, false);
if (
(local variable) int leader
leader
< 0)
{
(local variable) bool excludeKernel
excludeKernel
= true;
(local variable) int leader
leader
=
int cpu_pmu_counting_group.openEvent(ulong config, int groupFd, bool grouped, bool excludeKernel) @trusted

Opens one PERF_TYPE_HARDWARE event on the calling thread (pid == 0), any CPU (cpu == -1). groupFd` == -1` makes it a group leader; a leader carries the read format (`PERF_FORMAT_GROUP` when grouped``, plus the two time fields) and starts disabled. Returns the fd, or -1 on failure.

openEvent
(
(enum) core.sys.linux.perf_event.perf_hw_id

Generalized performance event event_id types, used by the attr.event_id parameter of the sys_perf_event_open() syscall:

perf_hw_id
.
(enum value) core.sys.linux.perf_event.perf_hw_id.PERF_COUNT_HW_CPU_CYCLES = 0
PERF_COUNT_HW_CPU_CYCLES
, -1, true, true);
} if (
(local variable) int leader
leader
< 0)
{
void std.stdio.writefln!char(in char[] fmt) @safe

Equivalent to writef(fmt, args, '\n').

writefln
("SKIP: perf_event_open failed — perf_event_paranoid too high, "
~ "seccomp, or no PMU on this host"); return 0; } const
(local variable) const(int) insns
insns
=
int cpu_pmu_counting_group.openEvent(ulong config, int groupFd, bool grouped, bool excludeKernel) @trusted

Opens one PERF_TYPE_HARDWARE event on the calling thread (pid == 0), any CPU (cpu == -1). groupFd` == -1` makes it a group leader; a leader carries the read format (`PERF_FORMAT_GROUP` when grouped``, plus the two time fields) and starts disabled. Returns the fd, or -1 on failure.

openEvent
(
(enum) core.sys.linux.perf_event.perf_hw_id

Generalized performance event event_id types, used by the attr.event_id parameter of the sys_perf_event_open() syscall:

perf_hw_id
.
(enum value) core.sys.linux.perf_event.perf_hw_id.PERF_COUNT_HW_INSTRUCTIONS = 1
PERF_COUNT_HW_INSTRUCTIONS
,
(local variable) int leader
leader
, true,
(local variable) bool excludeKernel
excludeKernel
);
if (
(local variable) const(int) insns
insns
< 0)
{
void std.stdio.writefln!char(in char[] fmt) @safe

Equivalent to writef(fmt, args, '\n').

writefln
("SKIP: could not add instructions to the group (errno on member open)");
int core.sys.posix.unistd.close(int) nothrow @nogc @trusted
close
(
(local variable) int leader
leader
);
return 0; }
void cpu_pmu_counting_group.ctl(int fd, uint request, bool wholeGroup) @trusted
ctl
(
(local variable) int leader
leader
,
(constant) int core.sys.linux.perf_event.PERF_EVENT_IOC_RESET = 9219
PERF_EVENT_IOC_RESET
, true);
void cpu_pmu_counting_group.ctl(int fd, uint request, bool wholeGroup) @trusted
ctl
(
(local variable) int leader
leader
,
(constant) int core.sys.linux.perf_event.PERF_EVENT_IOC_ENABLE = 9216

Ioctls that can be done on a perf event fd:

PERF_EVENT_IOC_ENABLE
, true);
void cpu_pmu_counting_group.workload()
workload
();
void cpu_pmu_counting_group.ctl(int fd, uint request, bool wholeGroup) @trusted
ctl
(
(local variable) int leader
leader
,
(constant) int core.sys.linux.perf_event.PERF_EVENT_IOC_DISABLE = 9217
PERF_EVENT_IOC_DISABLE
, true);
// Group read: nr, time_enabled, time_running, value[cycles], value[insns]. ulong[5]
(local variable) ulong[5] g
g
;
const
(local variable) const(long) got
got
=
long cpu_pmu_counting_group.readN(int fd, ulong[] buf) @trusted
readN
(
(local variable) int leader
leader
,
(local variable) ulong[5] g
g
[]);
int core.sys.posix.unistd.close(int) nothrow @nogc @trusted
close
(
(local variable) const(int) insns
insns
);
int core.sys.posix.unistd.close(int) nothrow @nogc @trusted
close
(
(local variable) int leader
leader
);
if (
(local variable) const(long) got
got
< cast(long)(5 * ulong.
(constant) ulong ulong.sizeof = 8LU
sizeof
))
{
void std.stdio.writefln!(char, const(long))(in char[] fmt, const(long) __param_1) @safe

Equivalent to writef(fmt, args, '\n').

writefln
("SKIP: short group read (%d bytes) — counters unavailable",
(local variable) const(long) got
got
);
return 0; } const
(local variable) const(ulong) nr
nr
=
(local variable) ulong[5] g
g
[0],
(local variable) const(ulong) enabled
enabled
=
(local variable) ulong[5] g
g
[1],
(local variable) const(ulong) running
running
=
(local variable) ulong[5] g
g
[2],
(local variable) const(ulong) cyc
cyc
=
(local variable) ulong[5] g
g
[3],
(local variable) const(ulong) ins
ins
=
(local variable) ulong[5] g
g
[4];
const
(local variable) const(double) groupScale
groupScale
=
(local variable) const(ulong) running
running
> 0 ? cast(double)
(local variable) const(ulong) enabled
enabled
/
(local variable) const(ulong) running
running
: double.
(constant) double double.nan = nan
nan
;
void std.stdio.writefln!(char, string)(in char[] fmt, string __param_1) @safe

Equivalent to writef(fmt, args, '\n').

writefln
("== Demo 1: fitting group (%s) ==",
(local variable) bool excludeKernel
excludeKernel
? "user-only" : "kernel+user");
void std.stdio.writefln!(char, const(ulong), const(ulong), const(ulong), const(double))(in char[] fmt, const(ulong) __param_1, const(ulong) __param_2, const(ulong) __param_3, const(double) __param_4) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" nr=%d time_enabled=%d ns time_running=%d ns scale=%.4f",
(local variable) const(ulong) nr
nr
,
(local variable) const(ulong) enabled
enabled
,
(local variable) const(ulong) running
running
,
(local variable) const(double) groupScale
groupScale
);
void std.stdio.writefln!(char, const(ulong), const(ulong), double)(in char[] fmt, const(ulong) __param_1, const(ulong) __param_2, double __param_3) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" cycles=%d instructions=%d IPC=%.3f",
(local variable) const(ulong) cyc
cyc
,
(local variable) const(ulong) ins
ins
,
(local variable) const(ulong) cyc
cyc
> 0 ? cast(double)
(local variable) const(ulong) ins
ins
/
(local variable) const(ulong) cyc
cyc
: double.
(constant) double double.nan = nan
nan
);
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
(" (grouped events co-schedule → time_running == time_enabled → exact)");
// ---- Demo 2: oversubscribe the PMCs → multiplexing scaling -------- // N separate single-event groups counting the SAME event over ONE // workload window. With N > general-purpose counters the kernel rotates // them, so each sees only part of the window (running < enabled). enum
(constant) int cpu_pmu_counting_group.run.N = 10
N
= 10;
int[
(constant) int cpu_pmu_counting_group.run.N = 10
N
]
(local variable) int[10] fds
fds
= -1;
int
(local variable) int opened
opened
= 0;
foreach (ref
(parameter) int fd
fd
;
(local variable) int[10] fds
fds
)
{
(local variable) int fd
fd
=
int cpu_pmu_counting_group.openEvent(ulong config, int groupFd, bool grouped, bool excludeKernel) @trusted

Opens one PERF_TYPE_HARDWARE event on the calling thread (pid == 0), any CPU (cpu == -1). groupFd` == -1` makes it a group leader; a leader carries the read format (`PERF_FORMAT_GROUP` when grouped``, plus the two time fields) and starts disabled. Returns the fd, or -1 on failure.

openEvent
(
(enum) core.sys.linux.perf_event.perf_hw_id

Generalized performance event event_id types, used by the attr.event_id parameter of the sys_perf_event_open() syscall:

perf_hw_id
.
(enum value) core.sys.linux.perf_event.perf_hw_id.PERF_COUNT_HW_INSTRUCTIONS = 1
PERF_COUNT_HW_INSTRUCTIONS
, -1, false,
(local variable) bool excludeKernel
excludeKernel
);
if (
(local variable) int fd
fd
>= 0)
(local variable) int opened
opened
++;
} if (
(local variable) int opened
opened
== 0)
{
void std.stdio.writefln!char(in char[] fmt) @safe

Equivalent to writef(fmt, args, '\n').

writefln
("SKIP: oversubscription demo could not open any event");
return 0; } foreach (
(parameter) int fd
fd
;
(local variable) int[10] fds
fds
)
if (
(local variable) int fd
fd
>= 0)
void cpu_pmu_counting_group.ctl(int fd, uint request, bool wholeGroup) @trusted
ctl
(
(local variable) int fd
fd
,
(constant) int core.sys.linux.perf_event.PERF_EVENT_IOC_RESET = 9219
PERF_EVENT_IOC_RESET
, false);
foreach (
(parameter) int fd
fd
;
(local variable) int[10] fds
fds
)
if (
(local variable) int fd
fd
>= 0)
void cpu_pmu_counting_group.ctl(int fd, uint request, bool wholeGroup) @trusted
ctl
(
(local variable) int fd
fd
,
(constant) int core.sys.linux.perf_event.PERF_EVENT_IOC_ENABLE = 9216

Ioctls that can be done on a perf event fd:

PERF_EVENT_IOC_ENABLE
, false);
void cpu_pmu_counting_group.workload()
workload
();
foreach (
(parameter) int fd
fd
;
(local variable) int[10] fds
fds
)
if (
(local variable) int fd
fd
>= 0)
void cpu_pmu_counting_group.ctl(int fd, uint request, bool wholeGroup) @trusted
ctl
(
(local variable) int fd
fd
,
(constant) int core.sys.linux.perf_event.PERF_EVENT_IOC_DISABLE = 9217
PERF_EVENT_IOC_DISABLE
, false);
void std.stdio.writefln!(char, int, int)(in char[] fmt, int __param_1, int __param_2) @safe

Equivalent to writef(fmt, args, '\n').

writefln
("\n== Demo 2: %d instruction counters, %d general-purpose PMCs ==",
(local variable) int opened
opened
, 6);
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
(" ev raw_running_count enabled_ns running_ns scale estimate");
bool
(local variable) bool sawMux
sawMux
= false;
foreach (
(parameter) ulong i
i
,
(parameter) int fd
fd
;
(local variable) int[10] fds
fds
)
{ if (
(local variable) int fd
fd
< 0)
continue; ulong[3]
(local variable) ulong[3] s
s
; // value, time_enabled, time_running
if (
long cpu_pmu_counting_group.readN(int fd, ulong[] buf) @trusted
readN
(
(local variable) int fd
fd
,
(local variable) ulong[3] s
s
[]) >= cast(long)(3 * ulong.
(constant) ulong ulong.sizeof = 8LU
sizeof
))
{ if (
(local variable) ulong[3] s
s
[2] <
(local variable) ulong[3] s
s
[1])
(local variable) bool sawMux
sawMux
= true;
if (
(local variable) ulong[3] s
s
[2] == 0)
// Enabled but never got a counter this window: the kernel's // `<not counted>` state — a zero read is not a measurement.
void std.stdio.writefln!(char, ulong, ulong, ulong, ulong)(in char[] fmt, ulong __param_1, ulong __param_2, ulong __param_3, ulong __param_4) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" %2d %18d %12d %12d — <not scheduled>",
(local variable) ulong i
i
,
(local variable) ulong[3] s
s
[0],
(local variable) ulong[3] s
s
[1],
(local variable) ulong[3] s
s
[2]);
else { const
(local variable) const(double) sc
sc
= cast(double)
(local variable) ulong[3] s
s
[1] /
(local variable) ulong[3] s
s
[2];
void std.stdio.writefln!(char, ulong, ulong, ulong, ulong, const(double), ulong)(in char[] fmt, ulong __param_1, ulong __param_2, ulong __param_3, ulong __param_4, const(double) __param_5, ulong __param_6) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" %2d %18d %12d %12d %5.2f %d",
(local variable) ulong i
i
,
(local variable) ulong[3] s
s
[0],
(local variable) ulong[3] s
s
[1],
(local variable) ulong[3] s
s
[2],
(local variable) const(double) sc
sc
, cast(ulong)(
(local variable) ulong[3] s
s
[0] *
(local variable) const(double) sc
sc
));
} }
int core.sys.posix.unistd.close(int) nothrow @nogc @trusted
close
(
(local variable) int fd
fd
);
}
void std.stdio.writefln!(char, string)(in char[] fmt, string __param_1) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" multiplexing observed: %s",
(local variable) bool sawMux
sawMux
? "yes (time_running < time_enabled — "
~ "raw counts are partial; the scaled estimate recovers the whole-window value)" : "no (this PMU has enough counters to co-schedule all events)"); return 0; } } int
int D main()
main
()
{ version (
linux
linux
)
return
int cpu_pmu_counting_group.run()
run
();
else { import std.stdio : writefln; writefln("SKIP: perf_event_open is Linux-only"); return 0; } }