mem-latency-numa.dhover×738all
#!/usr/bin/env dub
/+ dub.sdl:
    name "cpu_pmu_mem_latency_numa"
    platforms "linux"
    targetPath "build"
+/
/**
 * Precise memory-access sampling with data-source + NUMA-node attribution, pure D.
 *
 * The *precise data-source* concern of the analysis spine, exercised end to end
 * on the one engine that implements it on this host — AMD **IBS** (Instruction-
 * Based Sampling). It:
 *
 *   1. Opens the `ibs_op` PMU (its dynamic `type` read from
 *      `/sys/bus/event_source/devices/ibs_op/type`) with
 *      `PERF_SAMPLE_IP | ADDR | DATA_SRC | WEIGHT` (+ `PHYS_ADDR` when the host
 *      permits it), then strides a buffer larger than L3 to provoke DRAM loads.
 *      The kernel forwards a core-PMU `precise_ip` request to exactly this PMU
 *      (`forward_event_to_ibs`, `arch/x86/events/amd/ibs.c`); AMD has **no**
 *      PEBS, so the `cpu` PMU reports `max_precise == 0` and IBS is the *only*
 *      precise engine — the `cpu`/`precise_ip` fallback below is Intel-only and
 *      stays unexercised here.
 *   2. Decodes each sample's `perf_mem_data_src` union (the same bitfields the
 *      IBS driver fills from `IBS_OP_DATA2`/`DATA3`) into human level/op/snoop/
 *      TLB strings, matching `tools/perf/util/mem-events.c`.
 *   3. Classifies each sampled *data* address to a NUMA node two ways —
 *      `get_mempolicy(MPOL_F_NODE | MPOL_F_ADDR)` and `move_pages()` query mode
 *      (raw syscalls; see the note on libnuma below) — and compares them against
 *      the workload buffer's home node. This box is single-node, so every
 *      address resolves to node 0: the API round-trip is demonstrated, the
 *      cross-node *classification* is not (recorded as a host limit).
 *
 * `get_mempolicy`/`move_pages` are NOT in glibc (they live in libnuma, whose
 * functions are themselves thin syscall wrappers) and numactl ships no
 * `numa.pc`, so a `libs "numa"` link would be a hard build-time dependency that
 * a host without libnuma cannot satisfy — defeating "green on any host". We call
 * the two syscalls directly through the libc `syscall(2)` wrapper instead: no
 * external C library, identical kernel path.
 *
 * Companion to docs/research/cpu-pmu/precise-sampling.md
 *   § "Data-source & data-address sampling: AMD IBS" and
 *   § "From data address to NUMA node".
 *
 * Run with: dub run --single mem-latency-numa.d
 *
 * Environment recorded: Linux 6.18.26, AMD Ryzen 9 7940HX (Zen 4, family 0x19
 * model 0x61; `ibs_op` type 11, `zen4_ibs_extensions=1`), single NUMA node,
 * `/proc/sys/kernel/perf_event_paranoid` = -1, numactl 2.0.19 (headers only —
 * not linked), LDC 1.41 druntime `core.sys.linux.perf_event`.
 *
 * Portability: no precise PMU (no IBS and `cpu` `max_precise == 0`), a refused
 * `perf_event_open` (`perf_event_paranoid`, seccomp), no data-address samples,
 * or a non-Linux/non-NUMA host each print a `SKIP:` or reduced line and exit 0,
 * so CI stays green on any host.
 */
module 
(module) cpu_pmu_mem_latency_numa

Precise memory-access sampling with data-source + NUMA-node attribution, pure D.

The precise data-source concern of the analysis spine, exercised end to end on the one engine that implements it on this host — AMD IBS (Instruction- Based Sampling). It:

  1. Opens the ibs_op PMU (its dynamic type read from /sys/bus/event_source/devices/ibs_op/type) with PERF_SAMPLE_IP | ADDR | DATA_SRC | WEIGHT (+ PHYS_ADDR when the host permits it), then strides a buffer larger than L3 to provoke DRAM loads. The kernel forwards a core-PMU precise_ip request to exactly this PMU (forward_event_to_ibs, arch/x86/events/amd/ibs.c); AMD has no PEBS, so the cpu PMU reports max_precise == 0 and IBS is the only precise engine — the cpu/precise_ip fallback below is Intel-only and stays unexercised here.

  2. Decodes each sample's perf_mem_data_src union (the same bitfields the IBS driver fills from IBS_OP_DATA2/DATA3) into human level/op/snoop/ TLB strings, matching tools/perf/util/mem-events.c.

  3. Classifies each sampled data address to a NUMA node two ways — get_mempolicy(MPOL_F_NODE | MPOL_F_ADDR) and move_pages() query mode (raw syscalls; see the note on libnuma below) — and compares them against the workload buffer's home node. This box is single-node, so every address resolves to node 0: the API round-trip is demonstrated, the cross-node classification is not (recorded as a host limit).

get_mempolicy/move_pages are NOT in glibc (they live in libnuma, whose functions are themselves thin syscall wrappers) and numactl ships no numa.pc, so a libs "numa" link would be a hard build-time dependency that a host without libnuma cannot satisfy — defeating "green on any host". We call the two syscalls directly through the libc syscall(2) wrapper instead: no external C library, identical kernel path.

Companion to docs/research/cpu-pmu/precise-sampling.md § "Data-source & data-address sampling: AMD IBS" and § "From data address to NUMA node".

Run with: dub run --single mem-latency-numa.d

Environment recorded: Linux 6.18.26, AMD Ryzen 9 7940HX (Zen 4, family 0x19 model 0x61; ibs_op type 11, zen4_ibs_extensions=1), single NUMA node, /proc/sys/kernel/perf_event_paranoid = -1, numactl 2.0.19 (headers only — not linked), LDC 1.41 druntime core.sys.linux.perf_event.

Portability

no precise PMU (no IBS and cpu max_precise == 0), a refused perf_event_open (perf_event_paranoid, seccomp), no data-address samples, or a non-Linux/non-NUMA host each print a SKIP: or reduced line and exit 0, so CI stays green on any host.

cpu_pmu_mem_latency_numa
;
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_mem_latency_numa.close = int core.sys.posix.unistd.close(int) nothrow @nogc @trusted
close
,
(alias) cpu_pmu_mem_latency_numa.sysconf = long core.sys.posix.unistd.sysconf(int) nothrow @nogc @trusted
sysconf
,
(alias enum value) cpu_pmu_mem_latency_numa._SC_PAGESIZE = core.sys.posix.unistd._SC_PAGESIZE = 30
_SC_PAGESIZE
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(package) core.sys.posix.sys
sys
.
(module) core.sys.posix.sys.mman

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly, Alex Rønne Petersen@standardsThe Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
mman
: mmap,
(alias) cpu_pmu_mem_latency_numa.munmap = int core.sys.posix.sys.mman.munmap(void*, ulong) nothrow @nogc
munmap
,
(alias constant) cpu_pmu_mem_latency_numa.PROT_READ = int core.sys.posix.sys.mman.PROT_READ = 1
PROT_READ
,
(alias constant) cpu_pmu_mem_latency_numa.PROT_WRITE = int core.sys.posix.sys.mman.PROT_WRITE = 2
PROT_WRITE
,
(alias constant) cpu_pmu_mem_latency_numa.MAP_SHARED = int core.sys.posix.sys.mman.MAP_SHARED = 1
MAP_SHARED
,
(alias constant) cpu_pmu_mem_latency_numa.MAP_PRIVATE = int core.sys.posix.sys.mman.MAP_PRIVATE = 2
MAP_PRIVATE
,
(alias constant) cpu_pmu_mem_latency_numa.MAP_FAILED = void* core.sys.posix.sys.mman.MAP_FAILED = cast(void*)cast(size_t)18446744073709551615LU
MAP_FAILED
;
import
(package) core
core
.
(module) core.atomic

The atomic module provides basic support for lock-free concurrent programming.

Use the -preview=nosharedaccess compiler flag to detect unsafe individual read or write operations on shared data.

Source

core/atomic.d

Examples

int y = 2;
shared int x = y; // OK

//x++; // read modify write error
x.atomicOp!"+="(1); // OK
//y = x; // read error with preview flag
y = x.atomicLoad(); // OK
assert(y == 3);
//x = 5; // write error with preview flag
x.atomicStore(5); // OK
assert(x.atomicLoad() == 5);
@copyrightCopyright Sean Kelly 2005 - 2016.@licenseBoost License 1.0@authorsSean Kelly, Alex Rønne Petersen, Manu Evans
atomic
:
(alias template) cpu_pmu_mem_latency_numa.atomicLoad = core.atomic.atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)(auto ref return scope const T val) if (!is(T == shared(U), U) && !is(T == shared(inout(U)), U) && !is(T == shared(const(U)), U))

Loads 'val' from memory and returns it. The memory barrier specified by 'ms' is applied to the operation, which is fully sequenced by default. Valid memory orders are MemoryOrder.raw, MemoryOrder.acq, and MemoryOrder.seq.

@paramval The target variable.@returnsThe value of 'val'.
atomicLoad
,
(alias template) cpu_pmu_mem_latency_numa.atomicStore = core.atomic.atomicStore(MemoryOrder ms = MemoryOrder.seq, T, V)(ref T val, V newval) if (!is(T == shared) && !is(V == shared))

Writes 'newval' into 'val'. The memory barrier specified by 'ms' is applied to the operation, which is fully sequenced by default. Valid memory orders are MemoryOrder.raw, MemoryOrder.rel, and MemoryOrder.seq.

@paramval The target variable.@paramnewval The value to store.
atomicStore
,
(enum) core.atomic.MemoryOrder

Specifies the memory ordering semantics of an atomic operation.

@see
MemoryOrder
;
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_mem_latency_numa.writefln = std.stdio.writefln(alias fmt, A...)(A args) if (isSomeString!(typeof(fmt)))

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

writefln
,
(alias template) cpu_pmu_mem_latency_numa.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
;
import
(package) std
std
.
(module) std.algorithm

This package implements generic algorithms oriented towards the processing of sequences. Sequences processed by these functions define range-based interfaces. See also Reference on ranges and tutorial on ranges.

Algorithms are categorized into the following submodules:

Submodule Functions

| Searching | all any balancedParens boyerMooreFinder canFind commonPrefix count countUntil endsWith find findAdjacent findAmong findSkip findSplit findSplitAfter findSplitBefore minCount maxCount minElement maxElement minIndex maxIndex minPos maxPos skipOver startsWith until |

| Comparison | among castSwitch clamp cmp either equal isPermutation isSameLength levenshteinDistance levenshteinDistanceAndPath max min mismatch predSwitch |

| Iteration | cache cacheBidirectional chunkBy cumulativeFold each filter filterBidirectional fold group joiner map mean permutations reduce splitWhen splitter substitute sum uniq |

| Sorting | completeSort isPartitioned isSorted isStrictlyMonotonic ordered strictlyOrdered makeIndex merge multiSort nextEvenPermutation nextPermutation nthPermutation partialSort partition partition3 schwartzSort sort topN topNCopy topNIndex |

| Set operations (setops) | cartesianProduct largestPartialIntersection largestPartialIntersectionWeighted multiwayMerge multiwayUnion setDifference setIntersection setSymmetricDifference |

| Mutation | bringToFront copy fill initializeAll move moveAll moveSome moveEmplace moveEmplaceAll moveEmplaceSome remove reverse strip stripLeft stripRight swap swapRanges uninitializedFill |

Many functions in this package are parameterized with a predicate. The predicate may be any suitable callable type (a function, a delegate, a functor, or a lambda), or a compile-time string. The string may consist of any legal D expression that uses the symbol a (for unary functions) or the symbols a and b (for binary functions). These names will NOT interfere with other homonym symbols in user code because they are evaluated in a different context. The default for all binary comparison predicates is "a == b" for unordered operations and "a < b" for ordered operations.

Example

int[] a = ...;
static bool greater(int a, int b)
{
    return a > b;
}
sort!greater(a);           // predicate as alias
sort!((a, b) => a > b)(a); // predicate as a lambda.
sort!"a > b"(a);           // predicate as string
                           // (no ambiguity with array name)
sort(a);                   // no predicate, "a < b" is implicit

Source

std/algorithm/package.d

@copyrightAndrei Alexandrescu 2008-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu
algorithm
:
(alias template) cpu_pmu_mem_latency_numa.sort = std.algorithm.sorting.sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range r)

Sorts a random-access range according to the predicate less.

Performs O(r.length * log(r.length)) evaluations of less. If less involves expensive computations on the sort key, it may be worthwhile to use schwartzSort instead.

Stable sorting requires hasAssignableElements!Range to be true.

sort returns a SortedRange over the original range, allowing functions that can take advantage of sorted data to know that the range is sorted and adjust accordingly. The SortedRange is a wrapper around the original range, so both it and the original range are sorted. Other functions can't know that the original range has been sorted, but they can know that SortedRange has been sorted.

Preconditions

The predicate is expected to satisfy certain rules in order for sort to behave as expected - otherwise, the program may fail on certain inputs (but not others) when not compiled in release mode, due to the cursory assumeSorted check. Specifically, sort expects less(a,b) && less(b,c) to imply less(a,c) (transitivity), and, conversely, !less(a,b) && !less(b,c) to imply !less(a,c). Note that the default predicate ("a < b") does not always satisfy these conditions for floating point types, because the expression will always be false when either a or b is NaN. Use cmp instead.

Algorithms

Introsort is used for unstable sorting and Timsort is used for stable sorting. Each algorithm has benefits beyond stability. Introsort is generally faster but Timsort may achieve greater speeds on data with low entropy or if predicate calls are expensive. Introsort performs no allocations whereas Timsort will perform one or more allocations per call. Both algorithms have O(n log n) worst-case time complexity.

@paramless The predicate to sort by.@paramss The swapping strategy to use.@paramr The range to sort.@returnsThe initial range wrapped as a SortedRange with the predicate binaryFun!less.@see

assumeSorted

SortedRange

SwapStrategy

binaryFun

sort
,
(alias template) cpu_pmu_mem_latency_numa.min = std.algorithm.comparison.min(T...)(T args) if (T.length >= 2 && !is(CommonType!T == void))

Iterates the passed arguments and returns the minimum value.

@paramargs The values to select the minimum from. At least two arguments must be passed, and they must be comparable with <.@returnsThe minimum of the passed-in values. The type of the returned value is the type among the passed arguments that is able to store the smallest value. If at least one of the arguments is NaN, the result is an unspecified value. See minElement for examples on how to cope with NaNs.@seeminElement
min
;
// ---- libc / kernel seams ------------------------------------------------- // Anonymous mapping for the workload buffer (Linux value; the druntime posix // binding does not export MAP_ANON uniformly). enum
(constant) int cpu_pmu_mem_latency_numa.MAP_ANON = 32
MAP_ANON
= 0x20;
// PERF_SAMPLE_* live in a named D enum, so hoist the few this probe uses to // unqualified manifest constants for readable sample_type expressions. enum
(constant) core.sys.linux.perf_event.perf_event_sample_format cpu_pmu_mem_latency_numa.PERF_SAMPLE_IP = perf_event_sample_format.PERF_SAMPLE_IP
PERF_SAMPLE_IP
=
(enum) core.sys.linux.perf_event.perf_event_sample_format

Bits that can be set in attr.sample_type to request information in the overflow packets.

perf_event_sample_format
.
(enum value) core.sys.linux.perf_event.perf_event_sample_format.PERF_SAMPLE_IP = 1u
PERF_SAMPLE_IP
;
enum
(constant) core.sys.linux.perf_event.perf_event_sample_format cpu_pmu_mem_latency_numa.PERF_SAMPLE_ADDR = perf_event_sample_format.PERF_SAMPLE_ADDR
PERF_SAMPLE_ADDR
=
(enum) core.sys.linux.perf_event.perf_event_sample_format

Bits that can be set in attr.sample_type to request information in the overflow packets.

perf_event_sample_format
.
(enum value) core.sys.linux.perf_event.perf_event_sample_format.PERF_SAMPLE_ADDR = 8u
PERF_SAMPLE_ADDR
;
enum
(constant) core.sys.linux.perf_event.perf_event_sample_format cpu_pmu_mem_latency_numa.PERF_SAMPLE_WEIGHT = perf_event_sample_format.PERF_SAMPLE_WEIGHT
PERF_SAMPLE_WEIGHT
=
(enum) core.sys.linux.perf_event.perf_event_sample_format

Bits that can be set in attr.sample_type to request information in the overflow packets.

perf_event_sample_format
.
(enum value) core.sys.linux.perf_event.perf_event_sample_format.PERF_SAMPLE_WEIGHT = 16384u
PERF_SAMPLE_WEIGHT
;
enum
(constant) core.sys.linux.perf_event.perf_event_sample_format cpu_pmu_mem_latency_numa.PERF_SAMPLE_DATA_SRC = perf_event_sample_format.PERF_SAMPLE_DATA_SRC
PERF_SAMPLE_DATA_SRC
=
(enum) core.sys.linux.perf_event.perf_event_sample_format

Bits that can be set in attr.sample_type to request information in the overflow packets.

perf_event_sample_format
.
(enum value) core.sys.linux.perf_event.perf_event_sample_format.PERF_SAMPLE_DATA_SRC = 32768u
PERF_SAMPLE_DATA_SRC
;
enum
(constant) core.sys.linux.perf_event.perf_event_sample_format cpu_pmu_mem_latency_numa.PERF_SAMPLE_PHYS_ADDR = perf_event_sample_format.PERF_SAMPLE_PHYS_ADDR
PERF_SAMPLE_PHYS_ADDR
=
(enum) core.sys.linux.perf_event.perf_event_sample_format

Bits that can be set in attr.sample_type to request information in the overflow packets.

perf_event_sample_format
.
(enum value) core.sys.linux.perf_event.perf_event_sample_format.PERF_SAMPLE_PHYS_ADDR = 524288u
PERF_SAMPLE_PHYS_ADDR
;
// get_mempolicy(2) / move_pages(2) via the libc syscall wrapper. Numbers are // per-arch; verified against arch/x86/entry/syscalls/syscall_64.tbl (239 / // 279) and include/uapi/asm-generic/unistd.h (236 / 239) in the 7.1-rc6 tree. extern (C) long
long cpu_pmu_mem_latency_numa.syscall(long number, ...) nothrow @nogc
syscall
(long
(parameter) long number
number
, ...) @nogc nothrow;
version (
X86_64
X86_64
) { enum
(constant) int cpu_pmu_mem_latency_numa.SYS_get_mempolicy = 239
SYS_get_mempolicy
= 239; enum
(constant) int cpu_pmu_mem_latency_numa.SYS_move_pages = 279
SYS_move_pages
= 279; enum
(constant) bool cpu_pmu_mem_latency_numa.nodeSyscalls = true
nodeSyscalls
= true; }
else version (AArch64){ enum SYS_get_mempolicy = 236; enum SYS_move_pages = 239; enum nodeSyscalls = true; } else version (RISCV64){ enum SYS_get_mempolicy = 236; enum SYS_move_pages = 239; enum nodeSyscalls = true; } else { enum SYS_get_mempolicy = 0; enum SYS_move_pages = 0; enum nodeSyscalls = false; } // set_mempolicy(2)/get_mempolicy(2) flags — include/uapi/linux/mempolicy.h. enum
(constant) int cpu_pmu_mem_latency_numa.MPOL_F_NODE = 1
MPOL_F_NODE
= 1 << 0; // return the node of `addr` (with MPOL_F_ADDR)
enum
(constant) int cpu_pmu_mem_latency_numa.MPOL_F_ADDR = 2
MPOL_F_ADDR
= 1 << 1; // look the vma up by address
// Pin to one CPU so IBS per-thread sampling and the "home node" are stable. extern (C) int
int cpu_pmu_mem_latency_numa.sched_setaffinity(int pid, ulong cpusetsize, const(void)* mask) nothrow @nogc
sched_setaffinity
(int
(parameter) int pid
pid
,
(alias) object.size_t = ulong
size_t
(parameter) ulong cpusetsize
cpusetsize
, const(void)*
(parameter) const(void)* mask
mask
) @nogc nothrow;
// ---- perf_mem_data_src decode (include/uapi/linux/perf_event.h) ---------- // // The union is one u64 of contiguous bitfields; the shifts below are the // documented field positions. Constant names/values are the PERF_MEM_* // macros; the strings mirror tools/perf/util/mem-events.c so the decode // reads the same as `perf report -D`. ulong
ulong cpu_pmu_mem_latency_numa.bits(ulong v, uint shift, uint width) pure nothrow @nogc @safe
bits
(ulong
(parameter) ulong v
v
, uint
(parameter) uint shift
shift
, uint
(parameter) uint width
width
) @safe pure nothrow @nogc
=> (
(parameter) ulong v
v
>>
(parameter) uint shift
shift
) & ((1UL <<
(parameter) uint width
width
) - 1);
(alias) object.string = string
string
string cpu_pmu_mem_latency_numa.memOpStr(ulong ds) pure nothrow @nogc @safe
memOpStr
(ulong
(parameter) ulong ds
ds
) @safe pure nothrow @nogc
{ const
(local variable) const(ulong) op
op
=
ulong cpu_pmu_mem_latency_numa.bits(ulong v, uint shift, uint width) pure nothrow @nogc @safe
bits
(
(parameter) ulong ds
ds
, 0, 5);
if (
(local variable) const(ulong) op
op
& 0x02) return "LOAD";
if (
(local variable) const(ulong) op
op
& 0x04) return "STORE";
if (
(local variable) const(ulong) op
op
& 0x08) return "PFETCH";
if (
(local variable) const(ulong) op
op
& 0x10) return "EXEC";
return "N/A"; } // Composite level via mem_lvl_num (shift 33) + remote (37) + hops (43), // the path perf_mem__lvl_scnprintf takes when lvl_num is set.
(alias) object.string = string
string
string cpu_pmu_mem_latency_numa.memLvlStr(ulong ds) nothrow @safe
memLvlStr
(ulong
(parameter) ulong ds
ds
) @safe nothrow
{ static immutable
(alias) object.string = string
string
[16]
(immutable global) immutable(string[16]) cpu_pmu_mem_latency_numa.memLvlStr.lvlnum
lvlnum
= [
0x1: "L1", 0x2: "L2", 0x3: "L3", 0x4: "L4", 0x5: "L2 MHB", 0x6: "Memory-side Cache", 0x7: "L0", 0x8: "Uncached", 0x9: "CXL", 0xa: "I/O", 0xb: "Any cache", 0xc: "LFB/MAB", 0xd: "RAM", 0xe: "PMEM", 0xf: "N/A", ]; static immutable
(alias) object.string = string
string
[5]
(immutable global) immutable(string[5]) cpu_pmu_mem_latency_numa.memLvlStr.hops
hops
= [
"N/A", "core, same node", "node, same socket", "socket, same board", "board", ]; const
(local variable) const(ulong) lvl
lvl
=
ulong cpu_pmu_mem_latency_numa.bits(ulong v, uint shift, uint width) pure nothrow @nogc @safe
bits
(
(parameter) ulong ds
ds
, 5, 14);
const
(local variable) const(string) hit
hit
= (
(local variable) const(ulong) lvl
lvl
& 0x02) ? "hit" : (
(local variable) const(ulong) lvl
lvl
& 0x04) ? "miss" : "";
const
(local variable) const(uint) num
num
= cast(uint)
ulong cpu_pmu_mem_latency_numa.bits(ulong v, uint shift, uint width) pure nothrow @nogc @safe
bits
(
(parameter) ulong ds
ds
, 33, 4);
if (
(local variable) const(uint) num
num
!= 0 &&
(local variable) const(uint) num
num
!= 0xf)
{
(alias) object.string = string
string
(local variable) string s
s
;
if (
ulong cpu_pmu_mem_latency_numa.bits(ulong v, uint shift, uint width) pure nothrow @nogc @safe
bits
(
(parameter) ulong ds
ds
, 37, 1))
(local variable) string s
s
~= "Remote ";
const
(local variable) const(uint) h
h
= cast(uint)
ulong cpu_pmu_mem_latency_numa.bits(ulong v, uint shift, uint width) pure nothrow @nogc @safe
bits
(
(parameter) ulong ds
ds
, 43, 3);
if (
(local variable) const(uint) h
h
!= 0)
(local variable) string s
s
~=
(immutable global) immutable(string[5]) cpu_pmu_mem_latency_numa.memLvlStr.hops
hops
[
(local variable) const(uint) h
h
] ~ " ";
(local variable) string s
s
~=
(immutable global) immutable(string[16]) cpu_pmu_mem_latency_numa.memLvlStr.lvlnum
lvlnum
[
(local variable) const(uint) num
num
];
if (
(local variable) const(string) hit
hit
.
(field) ulong const(string).length
length
)
(local variable) string s
s
~= " " ~
(local variable) const(string) hit
hit
;
return
(local variable) string s
s
;
} return "N/A"; }
(alias) object.string = string
string
string cpu_pmu_mem_latency_numa.snoopStr(ulong ds) pure nothrow @nogc @safe
snoopStr
(ulong
(parameter) ulong ds
ds
) @safe pure nothrow @nogc
{ const
(local variable) const(ulong) s
s
=
ulong cpu_pmu_mem_latency_numa.bits(ulong v, uint shift, uint width) pure nothrow @nogc @safe
bits
(
(parameter) ulong ds
ds
, 19, 5);
if (
(local variable) const(ulong) s
s
& 0x10) return "HitM";
if (
(local variable) const(ulong) s
s
& 0x08) return "Miss";
if (
(local variable) const(ulong) s
s
& 0x04) return "Hit";
if (
(local variable) const(ulong) s
s
& 0x02) return "None";
if (
ulong cpu_pmu_mem_latency_numa.bits(ulong v, uint shift, uint width) pure nothrow @nogc @safe
bits
(
(parameter) ulong ds
ds
, 38, 2) & 0x02) return "Peer";
if (
ulong cpu_pmu_mem_latency_numa.bits(ulong v, uint shift, uint width) pure nothrow @nogc @safe
bits
(
(parameter) ulong ds
ds
, 38, 2) & 0x01) return "Fwd";
return "N/A"; }
(alias) object.string = string
string
string cpu_pmu_mem_latency_numa.tlbStr(ulong ds) pure nothrow @safe
tlbStr
(ulong
(parameter) ulong ds
ds
) @safe pure nothrow
{ const
(local variable) const(ulong) t
t
=
ulong cpu_pmu_mem_latency_numa.bits(ulong v, uint shift, uint width) pure nothrow @nogc @safe
bits
(
(parameter) ulong ds
ds
, 26, 7);
const
(local variable) const(string) where
where
= (
(local variable) const(ulong) t
t
& 0x08) ? "L1" : (
(local variable) const(ulong) t
t
& 0x10) ? "L2" : (
(local variable) const(ulong) t
t
& 0x20) ? "walker" : "";
const
(local variable) const(string) hm
hm
= (
(local variable) const(ulong) t
t
& 0x02) ? " hit" : (
(local variable) const(ulong) t
t
& 0x04) ? " miss" : "";
if (
(local variable) const(string) where
where
.
(field) ulong const(string).length
length
) return
(local variable) const(string) where
where
~
(local variable) const(string) hm
hm
;
return "N/A"; } // ---- NUMA node oracles --------------------------------------------------- /// Node of the page containing `addr`, or a negative -errno, via /// get_mempolicy(MPOL_F_NODE | MPOL_F_ADDR). numaif.h: /// long get_mempolicy(int *mode, ulong *nmask, ulong maxnode, /// void *addr, ulong flags); /// with these flags, `mode` receives the node number. int
int cpu_pmu_mem_latency_numa.nodeViaGetMempolicy(void* addr) nothrow @nogc @trusted

Node of the page containing addr, or a negative -errno, via get_mempolicy(MPOL_F_NODE | MPOL_F_ADDR). numaif.h: long get_mempolicy(int *mode, ulong nmask, ulong maxnode, void addr, ulong flags); with these flags, mode receives the node number.

nodeViaGetMempolicy
(void*
(parameter) void* addr
addr
) @trusted @nogc nothrow
{ static if (!nodeSyscalls) return -1; else { int
(local variable) int node
node
= -1;
const
(local variable) const(long) r
r
=
long cpu_pmu_mem_latency_numa.syscall(long number, ...) nothrow @nogc
syscall
(
(constant) int cpu_pmu_mem_latency_numa.SYS_get_mempolicy = 239
SYS_get_mempolicy
, &
(local variable) int node
node
, null, 0UL,
(parameter) void* addr
addr
,
cast(ulong)(
(constant) int cpu_pmu_mem_latency_numa.MPOL_F_NODE = 1
MPOL_F_NODE
|
(constant) int cpu_pmu_mem_latency_numa.MPOL_F_ADDR = 2
MPOL_F_ADDR
));
return
(local variable) const(long) r
r
== 0 ?
(local variable) int node
node
: cast(int)
(local variable) const(long) r
r
;
} } /// Node of the page containing `addr` via move_pages() query mode (nodes == /// NULL). numaif.h: /// long move_pages(int pid, ulong count, void **pages, /// const int *nodes, int *status, int flags); /// `status[0]` receives the node number (or a negative -errno). int
int cpu_pmu_mem_latency_numa.nodeViaMovePages(void* addr, ulong pageSize) nothrow @nogc @trusted

Node of the page containing addr via move_pages() query mode (nodes == NULL). numaif.h: long move_pages(int pid, ulong count, void **pages, const int nodes, int status, int flags); status[0] receives the node number (or a negative -errno).

nodeViaMovePages
(void*
(parameter) void* addr
addr
,
(alias) object.size_t = ulong
size_t
(parameter) ulong pageSize
pageSize
) @trusted @nogc nothrow
{ static if (!nodeSyscalls) return -1; else { void*
(local variable) void* page
page
= cast(void*)(cast(
(alias) object.size_t = ulong
size_t
)
(parameter) void* addr
addr
& ~(
(parameter) ulong pageSize
pageSize
- 1));
int
(local variable) int status
status
= int.
(constant) int int.min = -2147483648
min
;
const
(local variable) const(long) r
r
=
long cpu_pmu_mem_latency_numa.syscall(long number, ...) nothrow @nogc
syscall
(
(constant) int cpu_pmu_mem_latency_numa.SYS_move_pages = 279
SYS_move_pages
, 0, 1UL, &
(local variable) void* page
page
, null, &
(local variable) int status
status
, 0UL);
return
(local variable) const(long) r
r
== 0 ?
(local variable) int status
status
: cast(int)
(local variable) const(long) r
r
;
} } // ---- sysfs helper -------------------------------------------------------- /// Reads a small unsigned integer from a sysfs file, or -1 on any failure. long
long cpu_pmu_mem_latency_numa.readSysLong(string path) @trusted

Reads a small unsigned integer from a sysfs file, or -1 on any failure.

readSysLong
(
(alias) object.string = string
string
(parameter) string path
path
) @trusted
{ import
(package) std
std
.
(module) std.file

Utilities for manipulating files and scanning directories. Functions in this module handle files as a unit, e.g., read or write one file at a time. For opening files and manipulating them via handles refer to module std.stdio.

Category Functions
General exists isDir isFile isSymlink rename thisExePath
Directories chdir dirEntries getcwd mkdir mkdirRecurse rmdir rmdirRecurse tempDir
Files append copy read readText remove slurp write
Symlinks symlink readLink
Attributes attrIsDir attrIsFile attrIsSymlink getAttributes getLinkAttributes getSize setAttributes
Timestamp getTimes getTimesWin setTimes timeLastModified timeLastAccessed timeStatusChanged
Other DirEntry FileException PreserveAttributes SpanMode getAvailableDiskSpace

Source

std/file.d

@copyrightCopyright The D Language Foundation 2007 - 2011.@seeThe official tutorial for an introduction to working with files in D, module std.stdio for opening files and manipulating them via handles, and module std.path for manipulating path strings.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Jonathan M Davis
file
:
(alias template) readText = std.file.readText(S = string, R)(auto ref R name) if (isSomeString!S && (isSomeFiniteCharInputRange!R || is(StringTypeOf!R)))

Reads and validates (using $(REF validate, std, utf)) a text file. S can be an array of any character type. However, no width or endian conversions are performed. So, if the width or endianness of the characters in the given file differ from the width or endianness of the element type of S, then validation will fail.

    Params:
        S = the string type of the file
        name = string or range of characters representing the file _name

    Returns: Array of characters read.

    Throws: $(LREF FileException) if there is an error reading the file,
            $(REF UTFException, std, utf) on UTF decoding error.

    See_Also: $(REF read, std,file) for reading a binary file.
readText
;
import
(package) std
std
.
(module) std.string

String handling functions.

Category Functions
Searching
column
indexOf
indexOfAny
indexOfNeither
lastIndexOf
lastIndexOfAny
lastIndexOfNeither
Comparison
isNumeric
Mutation
capitalize
Pruning and Filling
center
chomp
chompPrefix
chop
detabber
detab
entab
entabber
leftJustify
outdent
rightJustify
strip
stripLeft
stripRight
wrap
Substitution
abbrev
soundex
soundexer
succ
tr
translate
Miscellaneous
assumeUTF
fromStringz
lineSplitter
representation
splitLines
toStringz
Objects of types string, wstring, and dstring are value types
and cannot be mutated element-by-element. For using mutation during building
strings, use char[], wchar[], or dchar[]. The xxxstring
types are preferable because they don't exhibit undesired aliasing, thus
making code more robust.

The following functions are publicly imported:

Module Functions
Publicly imported functions
std.algorithm
cmp, std,algorithm,comparison
count, std,algorithm,searching
endsWith, std,algorithm,searching
startsWith, std,algorithm,searching
std.array
join, std,array
replace, std,array
replaceInPlace, std,array
split, std,array
empty, std,array
std.format
format, std,format
sformat, std,format
std.uni
icmp, std,uni
toLower, std,uni
toLowerInPlace, std,uni
toUpper, std,uni
toUpperInPlace, std,uni
There is a rich set of functions for string handling defined in other modules.
Functions related to Unicode and ASCII are found in std.uni
and std.ascii, respectively. Other functions that have a
wider generality than just strings can be found in std.algorithm
and std.range.

Source

std/string.d

@seestd.algorithm and std.range for generic range algorithms , std.ascii for functions that work with ASCII strings , std.uni for functions that work with unicode strings@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Jonathan M Davis, and David L. 'SpottedTiger' Davis
string
:
(alias template) strip = std.string.strip(Range)(Range str) if (isSomeString!Range || isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range && !isConvertibleToString!Range && isSomeChar!(ElementEncodingType!Range))

Strips both leading and trailing whitespace (as defined by $(REF isWhite, std,uni)) or as specified in the second argument.

    Params:
        str = string or random access range of characters
        chars = string of characters to be stripped
        leftChars = string of leading characters to be stripped
        rightChars = string of trailing characters to be stripped

    Returns:
        slice of `str` stripped of leading and trailing whitespace
        or characters as specified in the second argument.

    See_Also:
        Generic stripping on ranges: $(REF _strip, std, algorithm, mutation)
strip
;
import
(package) std
std
.
(module) std.conv

A one-stop shop for converting values from one type to another.

Category Functions
Generic asOriginalType castFrom parse to toChars bitCast
Strings text wtext dtext writeText writeWText writeDText hexString
Numeric octal roundTo signed unsigned
Exceptions ConvException ConvOverflowException

Source

std/conv.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Shin Fujishiro, Adam D. Ruppe, Kenji Hara
conv
:
(alias template) to = std.conv.to(T)

The to template converts a value from one type _to another. The source type is deduced and the target type must be specified, for example the expression to!int(42.0) converts the number 42 from double _to int. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., to!double(42) does not do any checking because any int fits in a double.

Conversions from string _to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings _to signed types, the grammar recognized is: $(PRE $(I Integer): $(I Sign UnsignedInteger) $(I UnsignedInteger) $(I Sign): $(B +) $(B -))

For conversion _to unsigned types, the grammar recognized is: $(PRE $(I UnsignedInteger): $(I DecimalDigit) $(I DecimalDigit) $(I UnsignedInteger))

to
;
try return
string std.file.readText!(string, string)(ref string name) @safe

Reads and validates (using validate) a text file. S can be an array of any character type. However, no width or endian conversions are performed. So, if the width or endianness of the characters in the given file differ from the width or endianness of the element type of S, then validation will fail.

Examples

Read file with UTF-8 text.

write(deleteme, "abc"); // deleteme is the name of a temporary file
scope(exit) remove(deleteme);
string content = readText(deleteme);
assert(content == "abc");
@paramS the string type of the file@paramname string or range of characters representing the file name@returnsArray of characters read.@throwsFileException if there is an error reading the file, UTFException on UTF decoding error.@seeread for reading a binary file.
readText
(
(parameter) string path
path
).
string std.string.strip!string(string str) pure nothrow @nogc @safe

Strips both leading and trailing whitespace (as defined by isWhite) or as specified in the second argument.

Examples

import std.uni : lineSep, paraSep;
assert(strip("     hello world     ") ==
       "hello world");
assert(strip("\n\t\v\rhello world\n\t\v\r") ==
       "hello world");
assert(strip("hello world") ==
       "hello world");
assert(strip([lineSep] ~ "hello world" ~ [lineSep]) ==
       "hello world");
assert(strip([paraSep] ~ "hello world" ~ [paraSep]) ==
       "hello world");
@paramstr string or random access range of characters@paramchars string of characters to be stripped@paramleftChars string of leading characters to be stripped@paramrightChars string of trailing characters to be stripped@returnsslice of str stripped of leading and trailing whitespace or characters as specified in the second argument.@seeGeneric stripping on ranges: strip
strip
.
long std.conv.to!long.to!string(string __param_0) pure @safe

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));

assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 for float, 2^53-1 for double, and 2^64-1 for real (when real is 80-bit, e.g. on Intel machines).

// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');

// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');

// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to`!short` applies to an `int`, to!wstring applies to a string, to`!string` applies to a `double`, and to!(double[]) applies to an int[]. The conversion might throw an exception because ``to!short might fail the range check.

int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));

Stringize conversion from all types is supported.

  • String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable).

  • Converts array (other than strings) to string. Each element is converted by calling ``to!T.

  • Associative array to string conversion. Each element is converted by calling ``to!T.

  • Object to string conversion calls toString against the object or returns "null" if the object is null.

  • Struct to string conversion calls toString against the struct if it is defined.

  • For structs that do not define toString, the conversion to string produces the list of fields.

  • Enumerated types are converted to strings as their symbolic names.

  • Boolean values are converted to "true" or "false".

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    special case

    : Convert integral value to string in radix radix. radix must be a value from 2 to 36. value is treated as a signed value only if radix is 10. The characters A through Z are used to represent values 10 through 36 and their case is determined by the letterCase parameter.

  • All floating point types to all string types.

  • Pointer to string conversions convert the pointer to a size_t value. If pointer is char*, treat it as C-style strings. In that case, this function is @system.

See formatValue on how toString should be defined.

// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");

// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
       to!string(associativeArray) == `["1":2, "0":1]`);

// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");

// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);

auto c = to!(wchar[])(b);
assert(c == "abcx");

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!long;
catch (
(class) object.Exception

The base class of all errors that are safe to catch and handle.

In principle, only thrown objects derived from this class are safe to catch inside a catch block. Thrown objects not derived from Exception represent runtime errors that should not be caught, as certain runtime guarantees may not hold, making it unsafe to continue program execution.

Examples

bool gotCaught;
try
{
    throw new Exception("msg");
}
catch (Exception e)
{
    gotCaught = true;
    assert(e.msg == "msg");
}
assert(gotCaught);
Exception
)
return -1; } // ---- the workload -------------------------------------------------------- __gshared ulong
(__gshared global) ulong cpu_pmu_mem_latency_numa.sink
sink
;
/// Lay out `words` as one random permutation cycle of its own indices /// (Sattolo's algorithm → a single cycle). Chasing `i = words[i]` is then a /// dependent load per step whose target is unpredictable, so on a working set /// wider than L3 nearly every step misses to DRAM — the classic pointer-chase /// memory-latency pattern. Also faults every page in before classification. void
void cpu_pmu_mem_latency_numa.buildChase(ulong[] words) @safe

Lay out words as one random permutation cycle of its own indices (Sattolo's algorithm → a single cycle). Chasing i = words[i] is then a dependent load per step whose target is unpredictable, so on a working set wider than L3 nearly every step misses to DRAM — the classic pointer-chase memory-latency pattern. Also faults every page in before classification.

buildChase
(
(alias) object.size_t = ulong
size_t
[]
(parameter) ulong[] words
words
) @safe
{ foreach (
(local variable) ulong i
i
; 0 ..
(parameter) ulong[] words
words
.
(field) ulong ulong[].length
length
)
(parameter) ulong[] words
words
[
(local variable) ulong i
i
] =
(local variable) ulong i
i
;
ulong
(local variable) ulong rng
rng
= 0x9E3779B97F4A7C15UL;
for (
(alias) object.size_t = ulong
size_t
(local variable) ulong i
i
=
(parameter) ulong[] words
words
.
(field) ulong ulong[].length
length
- 1; i > 0; i--)
{
(local variable) ulong rng
rng
=
(local variable) ulong rng
rng
* 6364136223846793005UL + 1442695040888963407UL;
const
(local variable) const(ulong) j
j
= cast(
(alias) object.size_t = ulong
size_t
)(
(local variable) ulong rng
rng
%
(local variable) ulong i
i
); // 0 <= j < i keeps it a single cycle
const
(local variable) const(ulong) t
t
=
(parameter) ulong[] words
words
[
(local variable) ulong i
i
];
(parameter) ulong[] words
words
[
(local variable) ulong i
i
] =
(parameter) ulong[] words
words
[
(local variable) const(ulong) j
j
];
(parameter) ulong[] words
words
[
(local variable) const(ulong) j
j
] =
(local variable) const(ulong) t
t
;
} } /// `steps` dependent chases from `start`; returns the landing index (folded /// into a __gshared sink by the caller so the loads survive DCE).
(alias) object.size_t = ulong
size_t
ulong cpu_pmu_mem_latency_numa.chase(const(ulong[]) words, ulong start, ulong steps) @safe

steps dependent chases from start; returns the landing index (folded into a _gshared sink by the caller so the loads survive DCE).

chase
(const
(alias) object.size_t = ulong
size_t
[]
(parameter) const(ulong[]) words
words
,
(alias) object.size_t = ulong
size_t
(parameter) ulong start
start
,
(alias) object.size_t = ulong
size_t
(parameter) ulong steps
steps
) @safe
{
(alias) object.size_t = ulong
size_t
(local variable) ulong i
i
=
(parameter) ulong start
start
;
foreach (
(local variable) ulong _
_
; 0 ..
(parameter) ulong steps
steps
)
(local variable) ulong i
i
=
(parameter) const(ulong[]) words
words
[
(local variable) ulong i
i
];
return
(local variable) ulong i
i
;
} // ---- perf ring-buffer reader --------------------------------------------- /// Copies `n` bytes out of the perf data area at logical offset `logicalTail` /// (which may straddle the ring's wrap point) into `dst`. void
void cpu_pmu_mem_latency_numa.ringCopy(void* dst, const(ubyte)* dataStart, ulong dataSize, ulong logicalTail, ulong n) @system

Copies n bytes out of the perf data area at logical offset logicalTail (which may straddle the ring's wrap point) into dst.

ringCopy
(void*
(parameter) void* dst
dst
, const(ubyte)*
(parameter) const(ubyte)* dataStart
dataStart
, ulong
(parameter) ulong dataSize
dataSize
, ulong
(parameter) ulong logicalTail
logicalTail
,
(alias) object.size_t = ulong
size_t
(parameter) ulong n
n
) @system
{ auto
(local variable) ubyte* d
d
= cast(ubyte*)
(parameter) void* dst
dst
;
const
(local variable) const(ulong) off
off
= cast(
(alias) object.size_t = ulong
size_t
)(
(parameter) ulong logicalTail
logicalTail
%
(parameter) ulong dataSize
dataSize
);
foreach (
(local variable) ulong i
i
; 0 ..
(parameter) ulong n
n
)
(local variable) ubyte* d
d
[
(local variable) ulong i
i
] =
(parameter) const(ubyte)* dataStart
dataStart
[(
(local variable) const(ulong) off
off
+
(local variable) ulong i
i
) %
(parameter) ulong dataSize
dataSize
];
} /// One decoded PERF_RECORD_SAMPLE (only the fields this probe requests). struct
(struct) cpu_pmu_mem_latency_numa.Sample

One decoded PERF_RECORD_SAMPLE (only the fields this probe requests).

Sample
{ ulong
(field) ulong cpu_pmu_mem_latency_numa.Sample.ip
ip
,
(field) ulong cpu_pmu_mem_latency_numa.Sample.addr
addr
,
(field) ulong cpu_pmu_mem_latency_numa.Sample.weight
weight
,
(field) ulong cpu_pmu_mem_latency_numa.Sample.dataSrc
dataSrc
,
(field) ulong cpu_pmu_mem_latency_numa.Sample.physAddr
physAddr
;
} int
int cpu_pmu_mem_latency_numa.run()
run
()
{ const
(local variable) const(ulong) pageSize
pageSize
= cast(
(alias) object.size_t = ulong
size_t
)
long core.sys.posix.unistd.sysconf(int) nothrow @nogc @trusted
sysconf
(
(enum value) core.sys.posix.unistd._SC_PAGESIZE = 30
_SC_PAGESIZE
);
// ---- locate a precise-sampling PMU ---------------------------------- bool
(local variable) bool viaIbs
viaIbs
= true;
long
(local variable) long pmuType
pmuType
=
long cpu_pmu_mem_latency_numa.readSysLong(string path) @trusted

Reads a small unsigned integer from a sysfs file, or -1 on any failure.

readSysLong
("/sys/bus/event_source/devices/ibs_op/type");
int
(local variable) int maxPrecise
maxPrecise
= 0;
if (
(local variable) long pmuType
pmuType
< 0)
{
(local variable) bool viaIbs
viaIbs
= false;
(local variable) int maxPrecise
maxPrecise
= cast(int)
long cpu_pmu_mem_latency_numa.readSysLong(string path) @trusted

Reads a small unsigned integer from a sysfs file, or -1 on any failure.

readSysLong
("/sys/bus/event_source/devices/cpu/caps/max_precise");
if (
(local variable) int maxPrecise
maxPrecise
<= 0)
{
void std.stdio.writefln!(char, int)(in char[] fmt, int __param_1) @safe

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

writefln
("SKIP: no precise-sampling PMU — no AMD IBS (`ibs_op`) and "
~ "`cpu` max_precise == %d (Intel needs PEBS/precise_ip>0)",
(local variable) int maxPrecise
maxPrecise
);
return 0; }
(local variable) long pmuType
pmuType
=
(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
; // cpu-PMU precise fallback
} const
(local variable) const(bool) zen4
zen4
=
long cpu_pmu_mem_latency_numa.readSysLong(string path) @trusted

Reads a small unsigned integer from a sysfs file, or -1 on any failure.

readSysLong
("/sys/bus/event_source/devices/ibs_op/caps/zen4_ibs_extensions") == 1;
// ---- NUMA topology -------------------------------------------------- int
(local variable) int nodesOnline
nodesOnline
= 1;
{ import
(package) std
std
.
(module) std.file

Utilities for manipulating files and scanning directories. Functions in this module handle files as a unit, e.g., read or write one file at a time. For opening files and manipulating them via handles refer to module std.stdio.

Category Functions
General exists isDir isFile isSymlink rename thisExePath
Directories chdir dirEntries getcwd mkdir mkdirRecurse rmdir rmdirRecurse tempDir
Files append copy read readText remove slurp write
Symlinks symlink readLink
Attributes attrIsDir attrIsFile attrIsSymlink getAttributes getLinkAttributes getSize setAttributes
Timestamp getTimes getTimesWin setTimes timeLastModified timeLastAccessed timeStatusChanged
Other DirEntry FileException PreserveAttributes SpanMode getAvailableDiskSpace

Source

std/file.d

@copyrightCopyright The D Language Foundation 2007 - 2011.@seeThe official tutorial for an introduction to working with files in D, module std.stdio for opening files and manipulating them via handles, and module std.path for manipulating path strings.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Jonathan M Davis
file
:
(alias template) dirEntries = std.file.dirEntries(bool useDIP1000 = dip1000Enabled)(string path, SpanMode mode, bool followSymlink = true)

Returns an $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of DirEntry that lazily iterates a given directory, also provides two ways of foreach iteration. The iteration variable can be of type string if only the name is needed, or DirEntry if additional details are needed. The span _mode dictates how the directory is traversed. The name of each iterated directory entry contains the absolute or relative path (depending on pathname).

    Note: The order of returned directory entries is as it is provided by the
    operating system / filesystem, and may not follow any particular sorting.

    Params:
        useDIP1000 = used to instantiate this function separately for code with
                     and without -preview=dip1000 compiler switch, because it
                     affects the ABI of this function. Set automatically -
                     don't touch.

        path = The directory to iterate over.
               If empty, the current directory will be iterated.

        pattern = Optional string with wildcards, such as $(RED
                  "*.d"). When present, it is used to filter the
                  results by their file name. The supported wildcard
                  strings are described under $(REF globMatch,
                  std,_path).

        mode = Whether the directory's sub-directories should be
               iterated in depth-first post-order ($(LREF depth)),
               depth-first pre-order ($(LREF breadth)), or not at all
               ($(LREF shallow)).

        followSymlink = Whether symbolic links which point to directories
                         should be treated as directories and their contents
                         iterated over.

    Returns:
        An $(REF_ALTTEXT input range, isInputRange,std,range,primitives) of
        $(LREF DirEntry).

    Throws:
        $(UL
        $(LI $(LREF FileException) if the $(B path) directory does not exist or read permission is denied.)
        $(LI $(LREF FileException) if $(B mode) is not `shallow` and a subdirectory cannot be read.)
        )

Example:

// Iterate a directory in depth foreach (string name; dirEntries("destroy/me", SpanMode.depth)) { remove(name); }

// Iterate the current directory in breadth foreach (string name; dirEntries("", SpanMode.breadth)) { writeln(name); }

// Iterate a directory and get detailed info about it foreach (DirEntry e; dirEntries("dmd-testing", SpanMode.breadth)) { writeln(e.name, "\t", e.size); }

// Iterate over all *.d files in current directory and all its subdirectories auto dFiles = dirEntries("", SpanMode.depth).filter!(f => f.name.endsWith(".d")); foreach (d; dFiles) writeln(d.name);

// Hook it up with std.parallelism to compile them all in parallel: foreach (d; parallel(dFiles, 1)) //passes by 1 file to each thread { string cmd = "dmd -c " ~ d.name; writeln(cmd); std.process.executeShell(cmd); }

// Iterate over all D source files in current directory and all its // subdirectories auto dFiles = dirEntries("","*.{d,di}",SpanMode.depth); foreach (d; dFiles) writeln(d.name);

To handle subdirectories with denied read permission, use SpanMode.shallow:

void scan(string path) { foreach (DirEntry entry; dirEntries(path, SpanMode.shallow)) { try { writeln(entry.name); if (entry.isDir) scan(entry.name); } catch (FileException fe) { continue; } // ignore } }

scan(""); ---

dirEntries
,
(enum) std.file.SpanMode

Dictates directory spanning policy for dirEntries (see below).

Examples

import std.algorithm.comparison : equal;
import std.algorithm.iteration : map;
import std.algorithm.sorting : sort;
import std.array : array;
import std.path : buildPath, relativePath;

auto root = deleteme ~ "root";
scope(exit) root.rmdirRecurse;
root.mkdir;

root.buildPath("animals").mkdir;
root.buildPath("animals", "cat").mkdir;

alias removeRoot = (return scope e) => e.relativePath(root);

assert(root.dirEntries(SpanMode.depth).map!removeRoot.equal(
    [buildPath("animals", "cat"), "animals"]));

assert(root.dirEntries(SpanMode.breadth).map!removeRoot.equal(
    ["animals", buildPath("animals", "cat")]));

root.buildPath("plants").mkdir;

assert(root.dirEntries(SpanMode.shallow).array.sort.map!removeRoot.equal(
    ["animals", "plants"]));
SpanMode
,
(alias template) exists = std.file.exists(R)(R name) if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)

Determine whether the given file (or directory) _exists. Params: name = string or range of characters representing the file _name Returns: true if the file name specified as input exists

exists
;
import
(package) std
std
.
(module) std.algorithm

This package implements generic algorithms oriented towards the processing of sequences. Sequences processed by these functions define range-based interfaces. See also Reference on ranges and tutorial on ranges.

Algorithms are categorized into the following submodules:

Submodule Functions

| Searching | all any balancedParens boyerMooreFinder canFind commonPrefix count countUntil endsWith find findAdjacent findAmong findSkip findSplit findSplitAfter findSplitBefore minCount maxCount minElement maxElement minIndex maxIndex minPos maxPos skipOver startsWith until |

| Comparison | among castSwitch clamp cmp either equal isPermutation isSameLength levenshteinDistance levenshteinDistanceAndPath max min mismatch predSwitch |

| Iteration | cache cacheBidirectional chunkBy cumulativeFold each filter filterBidirectional fold group joiner map mean permutations reduce splitWhen splitter substitute sum uniq |

| Sorting | completeSort isPartitioned isSorted isStrictlyMonotonic ordered strictlyOrdered makeIndex merge multiSort nextEvenPermutation nextPermutation nthPermutation partialSort partition partition3 schwartzSort sort topN topNCopy topNIndex |

| Set operations (setops) | cartesianProduct largestPartialIntersection largestPartialIntersectionWeighted multiwayMerge multiwayUnion setDifference setIntersection setSymmetricDifference |

| Mutation | bringToFront copy fill initializeAll move moveAll moveSome moveEmplace moveEmplaceAll moveEmplaceSome remove reverse strip stripLeft stripRight swap swapRanges uninitializedFill |

Many functions in this package are parameterized with a predicate. The predicate may be any suitable callable type (a function, a delegate, a functor, or a lambda), or a compile-time string. The string may consist of any legal D expression that uses the symbol a (for unary functions) or the symbols a and b (for binary functions). These names will NOT interfere with other homonym symbols in user code because they are evaluated in a different context. The default for all binary comparison predicates is "a == b" for unordered operations and "a < b" for ordered operations.

Example

int[] a = ...;
static bool greater(int a, int b)
{
    return a > b;
}
sort!greater(a);           // predicate as alias
sort!((a, b) => a > b)(a); // predicate as a lambda.
sort!"a > b"(a);           // predicate as string
                           // (no ambiguity with array name)
sort(a);                   // no predicate, "a < b" is implicit

Source

std/algorithm/package.d

@copyrightAndrei Alexandrescu 2008-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu
algorithm
:
(alias template) startsWith = std.algorithm.searching.startsWith(alias pred = (a, b) => a == b, Range, Needles...)(Range doesThisStart, Needles withOneOfThese) if (isInputRange!Range && (Needles.length > 1) && allSatisfy!(canTestStartsWith!(pred, Range), Needles))

Checks whether the given $(REF_ALTTEXT input range, isInputRange, std,range,primitives) starts with (one of) the given needle(s) or, if no needles are given, if its front element fulfils predicate pred.

For more information about pred see $(LREF find).

Params:

    pred = Predicate to use in comparing the elements of the haystack and the
        needle(s). Mandatory if no needles are given.

    doesThisStart = The input range to check.

    withOneOfThese = The needles against which the range is to be checked,
        which may be individual elements or input ranges of elements.

    withThis = The single needle to check, which may be either a single element
        or an input range of elements.

Returns:

0 if the needle(s) do not occur at the beginning of the given range; otherwise the position of the matching needle, that is, 1 if the range starts with withOneOfThese[0], 2 if it starts with withOneOfThese[1], and so on.

In the case where doesThisStart starts with multiple of the ranges or elements in withOneOfThese, then the shortest one matches (if there are two which match which are of the same length (e.g. "a" and 'a'), then the left-most of them in the argument list matches).

In the case when no needle parameters are given, return true iff front of doesThisStart fulfils predicate pred.

startsWith
;
import
(package) std
std
.
(module) std.path

This module is used to manipulate path strings.

All functions, with the exception of expandTilde (and in some cases absolutePath and relativePath), are pure string manipulation functions; they don't depend on any state outside the program, nor do they perform any actual file system actions. This has the consequence that the module does not make any distinction between a path that points to a directory and a path that points to a file, and it does not know whether or not the object pointed to by the path actually exists in the file system. To differentiate between these cases, use isDir and exists.

Note that on Windows, both the backslash (\) and the slash (/) are in principle valid directory separators. This module treats them both on equal footing, but in cases where a new separator is added, a backslash will be used. Furthermore, the buildNormalizedPath function will replace all slashes with backslashes on that platform.

In general, the functions in this module assume that the input paths are well-formed. (That is, they should not contain invalid characters, they should follow the file system's path format, etc.) The result of calling a function on an ill-formed path is undefined. When there is a chance that a path or a file name is invalid (for instance, when it has been input by the user), it may sometimes be desirable to use the isValidFilename and isValidPath functions to check this.

Most functions do not perform any memory allocations, and if a string is returned, it is usually a slice of an input string. If a function allocates, this is explicitly mentioned in the documentation.

Category Functions
Normalization absolutePath asAbsolutePath asNormalizedPath asRelativePath buildNormalizedPath buildPath chainPath expandTilde
Partitioning baseName dirName dirSeparator driveName pathSeparator pathSplitter relativePath rootName stripDrive
Validation isAbsolute isDirSeparator isRooted isValidFilename isValidPath
Extension defaultExtension extension setExtension stripExtension withDefaultExtension withExtension
Other filenameCharCmp filenameCmp globMatch CaseSensitive

Source

std/path.d

@authorsLars Tandle Kyllingstad, Walter Bright, Grzegorz Adam Hankiewicz, Thomas Khne, Andrei Alexandrescu@copyrightCopyright (c) 2000-2014, the authors. All rights reserved.@licenseBoost License 1.0
path
:
(alias template) baseName = std.path.baseName(R)(return scope R path) if (isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) && !isSomeString!R)

Params: cs = Whether or not suffix matching is case-sensitive. path = A path name. It can be a string, or any random-access range of characters. suffix = An optional suffix to be removed from the file name. Returns: The name of the file in the path name, without any leading directory and with an optional suffix chopped off.

    If `suffix` is specified, it will be compared to `path`
    using `filenameCmp!cs`,
    where `cs` is an optional template parameter determining whether
    the comparison is case sensitive or not.  See the
    $(LREF filenameCmp) documentation for details.

    Note:
    This function $(I only) strips away the specified suffix, which
    doesn't necessarily have to represent an extension.
    To remove the extension from a path, regardless of what the extension
    is, use $(LREF stripExtension).
    To obtain the filename without leading directories and without
    an extension, combine the functions like this:
    ---
    assert(baseName(stripExtension("dir/file.ext")) == "file");
    ---

    Standards:
    This function complies with
    $(LINK2 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/basename.html,
    the POSIX requirements for the 'basename' shell utility)
    (with suitable adaptations for Windows paths).
baseName
;
if (
bool std.file.exists!string(string name) nothrow @nogc @safe

Determine whether the given file (or directory) exists.

@paramname string or range of characters representing the file name@returnstrue if the file name specified as input exists
exists
("/sys/devices/system/node"))
{ int
(local variable) int c
c
= 0;
foreach (
(local variable) std.file.DirEntry e
e
;
std.file._DirIterator!false std.file.dirEntries!false(string path, std.file.SpanMode mode, bool followSymlink = true) @system

Returns an input range of DirEntry that lazily iterates a given directory, also provides two ways of foreach iteration. The iteration variable can be of type string if only the name is needed, or DirEntry if additional details are needed. The span mode dictates how the directory is traversed. The name of each iterated directory entry contains the absolute or relative path (depending on pathname).

Note

The order of returned directory entries is as it is provided by the operating system / filesystem, and may not follow any particular sorting.

Example

// Iterate a directory in depth
foreach (string name; dirEntries("destroy/me", SpanMode.depth))
{
    remove(name);
}

// Iterate the current directory in breadth
foreach (string name; dirEntries("", SpanMode.breadth))
{
    writeln(name);
}

// Iterate a directory and get detailed info about it
foreach (DirEntry e; dirEntries("dmd-testing", SpanMode.breadth))
{
    writeln(e.name, "\t", e.size);
}

// Iterate over all *.d files in current directory and all its subdirectories
auto dFiles = dirEntries("", SpanMode.depth).filter!(f => f.name.endsWith(".d"));
foreach (d; dFiles)
    writeln(d.name);

// Hook it up with std.parallelism to compile them all in parallel:
foreach (d; parallel(dFiles, 1)) //passes by 1 file to each thread
{
    string cmd = "dmd -c "  ~ d.name;
    writeln(cmd);
    std.process.executeShell(cmd);
}

// Iterate over all D source files in current directory and all its
// subdirectories
auto dFiles = dirEntries("","*.{d,di}",SpanMode.depth);
foreach (d; dFiles)
    writeln(d.name);

To handle subdirectories with denied read permission, use SpanMode.shallow:

void scan(string path)
{
    foreach (DirEntry entry; dirEntries(path, SpanMode.shallow))
    {
        try
        {
            writeln(entry.name);
            if (entry.isDir)
                scan(entry.name);
        }
        catch (FileException fe) { continue; } // ignore
    }
}

scan("");

Examples

Duplicate functionality of D1's std.file.listdir():

string[] listdir(string pathname)
{
    import std.algorithm.iteration : map, filter;
    import std.array : array;
    import std.path : baseName;

    return dirEntries(pathname, SpanMode.shallow)
        .filter!(a => a.isFile)
        .map!((return a) => baseName(a.name))
        .array;
}

// Can be safe only with -preview=dip1000
@safe void main(string[] args)
{
    import std.stdio : writefln;

    string[] files = listdir(args[1]);
    writefln("%s", files);
}
@paramuseDIP1000 used to instantiate this function separately for code with and without -preview=dip1000 compiler switch, because it affects the ABI of this function. Set automatically - don't touch.@parampath The directory to iterate over. If empty, the current directory will be iterated.@parampattern Optional string with wildcards, such as "*.d". When present, it is used to filter the results by their file name. The supported wildcard strings are described under globMatch.@parammode Whether the directory's sub-directories should be iterated in depth-first post-order (depth), depth-first pre-order (breadth), or not at all (shallow).@paramfollowSymlink Whether symbolic links which point to directories should be treated as directories and their contents iterated over.@returnsAn input range of DirEntry.@throws
  • FileException if the path directory does not exist or read permission is denied.

  • FileException if mode is not shallow and a subdirectory cannot be read.

dirEntries
("/sys/devices/system/node",
(enum) std.file.SpanMode

Dictates directory spanning policy for dirEntries (see below).

Examples

import std.algorithm.comparison : equal;
import std.algorithm.iteration : map;
import std.algorithm.sorting : sort;
import std.array : array;
import std.path : buildPath, relativePath;

auto root = deleteme ~ "root";
scope(exit) root.rmdirRecurse;
root.mkdir;

root.buildPath("animals").mkdir;
root.buildPath("animals", "cat").mkdir;

alias removeRoot = (return scope e) => e.relativePath(root);

assert(root.dirEntries(SpanMode.depth).map!removeRoot.equal(
    [buildPath("animals", "cat"), "animals"]));

assert(root.dirEntries(SpanMode.breadth).map!removeRoot.equal(
    ["animals", buildPath("animals", "cat")]));

root.buildPath("plants").mkdir;

assert(root.dirEntries(SpanMode.shallow).array.sort.map!removeRoot.equal(
    ["animals", "plants"]));
SpanMode
.
(enum value) std.file.SpanMode.shallow = 0

Only spans one directory.

shallow
))
if (
(local variable) std.file.DirEntry e
e
.
string std.path.baseName!(immutable(char))(return scope string path) pure nothrow @nogc @safe

Note

This function only strips away the specified suffix, which doesn't necessarily have to represent an extension. To remove the extension from a path, regardless of what the extension is, use stripExtension. To obtain the filename without leading directories and without an extension, combine the functions like this:

assert(baseName(stripExtension("dir/file.ext")) == "file");
@paramcs Whether or not suffix matching is case-sensitive.@parampath A path name. It can be a string, or any random-access range of characters.@paramsuffix An optional suffix to be removed from the file name.@returns

The name of the file in the path name, without any leading directory and with an optional suffix chopped off.

If suffix is specified, it will be compared to path using filenameCmp!cs, where cs is an optional template parameter determining whether the comparison is case sensitive or not. See the filenameCmp documentation for details.

@standardsThis function complies with the POSIX requirements for the 'basename' shell utility (with suitable adaptations for Windows paths).
baseName
.
bool std.algorithm.searching.startsWith!("a == b", string, string)(string doesThisStart, string withThis) pure nothrow @nogc @safe

Checks whether the given input range starts with (one of) the given needle(s) or, if no needles are given, if its front element fulfils predicate pred.

For more information about pred see find.

@parampred Predicate to use in comparing the elements of the haystack and the needle(s). Mandatory if no needles are given.@paramdoesThisStart The input range to check.@paramwithOneOfThese The needles against which the range is to be checked, which may be individual elements or input ranges of elements.@paramwithThis The single needle to check, which may be either a single element or an input range of elements.@returns

0 if the needle(s) do not occur at the beginning of the given range; otherwise the position of the matching needle, that is, 1 if the range starts with withOneOfThese[0], 2 if it starts with withOneOfThese[1], and so on.

In the case where doesThisStart starts with multiple of the ranges or elements in withOneOfThese, then the shortest one matches (if there are two which match which are of the same length (e.g. "a" and 'a'), then the left-most of them in the argument list matches).

In the case when no needle parameters are given, return true iff front of doesThisStart fulfils predicate pred.

startsWith
("node"))
(local variable) int c
c
++;
if (
(local variable) int c
c
> 0)
(local variable) int nodesOnline
nodesOnline
=
(local variable) int c
c
;
} } // Pin to CPU 0 for a stable per-thread IBS context and home node. ulong[16]
(local variable) ulong[16] cpuMask
cpuMask
;
(local variable) ulong[16] cpuMask
cpuMask
[0] = 1;
int cpu_pmu_mem_latency_numa.sched_setaffinity(int pid, ulong cpusetsize, const(void)* mask) nothrow @nogc
sched_setaffinity
(0,
(local variable) ulong[16] cpuMask
cpuMask
.
(constant) ulong ulong[16].sizeof = 128LU
sizeof
,
(local variable) ulong[16] cpuMask
cpuMask
.
(constant) ulong* ulong[16].ptr = &cpuMask
ptr
);
// ---- workload buffer + its home node -------------------------------- enum
(constant) int cpu_pmu_mem_latency_numa.run.bufBytes = 67108864
bufBytes
= 64 * 1024 * 1024; // > per-CCX L3, so misses reach DRAM
void*
(local variable) void* raw
raw
= mmap(null,
(constant) int cpu_pmu_mem_latency_numa.run.bufBytes = 67108864
bufBytes
,
(constant) int core.sys.posix.sys.mman.PROT_READ = 1
PROT_READ
|
(constant) int core.sys.posix.sys.mman.PROT_WRITE = 2
PROT_WRITE
,
(constant) int core.sys.posix.sys.mman.MAP_PRIVATE = 2
MAP_PRIVATE
|
(constant) int cpu_pmu_mem_latency_numa.MAP_ANON = 32
MAP_ANON
, -1, 0);
if (
(local variable) void* raw
raw
==
(constant) void* core.sys.posix.sys.mman.MAP_FAILED = cast(void*)cast(size_t)18446744073709551615LU
MAP_FAILED
)
{
void std.stdio.writefln!(char, int)(in char[] fmt, int __param_1) @safe

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

writefln
("SKIP: could not mmap a %d MiB workload buffer",
(constant) int cpu_pmu_mem_latency_numa.run.bufBytes = 67108864
bufBytes
>> 20);
return 0; } auto
(local variable) ulong[] words
words
= (cast(
(alias) object.size_t = ulong
size_t
*)
(local variable) void* raw
raw
)[0 ..
(constant) int cpu_pmu_mem_latency_numa.run.bufBytes = 67108864
bufBytes
/
(ulong) ulong
size_t
.
(constant) ulong ulong.sizeof = 8LU
sizeof
];
void cpu_pmu_mem_latency_numa.buildChase(ulong[] words) @safe

Lay out words as one random permutation cycle of its own indices (Sattolo's algorithm → a single cycle). Chasing i = words[i] is then a dependent load per step whose target is unpredictable, so on a working set wider than L3 nearly every step misses to DRAM — the classic pointer-chase memory-latency pattern. Also faults every page in before classification.

buildChase
(
(local variable) ulong[] words
words
); // also faults every page in before classifying
const
(local variable) const(int) homeNode
homeNode
=
int cpu_pmu_mem_latency_numa.nodeViaGetMempolicy(void* addr) nothrow @nogc @trusted

Node of the page containing addr, or a negative -errno, via get_mempolicy(MPOL_F_NODE | MPOL_F_ADDR). numaif.h: long get_mempolicy(int *mode, ulong nmask, ulong maxnode, void addr, ulong flags); with these flags, mode receives the node number.

nodeViaGetMempolicy
(
(local variable) void* raw
raw
);
// ---- open the sampling event ---------------------------------------- // Try richest sample set first (with PHYS_ADDR), then drop PHYS_ADDR; // and prefer kernel exclusion, then fall back to unfiltered — so a // stricter host still yields a working event. // // IBS filtering surprise: this Zen 4 lacks IBS_CAPS_BIT63_FILTER, so a // bare `exclude_kernel`/`exclude_hv` is EINVAL (perf_ibs_init, // arch/x86/events/amd/ibs.c). Kernel/user filtering must instead engage // the software filter — the `swfilt` bit (config2:0, IBS_SW_FILTER_MASK). // `exclude_hv` is never set: IBS rejects it outright. enum
(constant) ulong cpu_pmu_mem_latency_numa.run.swfilt = 1LU
swfilt
= 1UL; // config2:0
enum
(constant) core.sys.linux.perf_event.perf_event_sample_format cpu_pmu_mem_latency_numa.run.baseType = cast(perf_event_sample_format)49161u
baseType
=
(constant) core.sys.linux.perf_event.perf_event_sample_format cpu_pmu_mem_latency_numa.PERF_SAMPLE_IP = perf_event_sample_format.PERF_SAMPLE_IP
PERF_SAMPLE_IP
|
(constant) core.sys.linux.perf_event.perf_event_sample_format cpu_pmu_mem_latency_numa.PERF_SAMPLE_ADDR = perf_event_sample_format.PERF_SAMPLE_ADDR
PERF_SAMPLE_ADDR
|
(constant) core.sys.linux.perf_event.perf_event_sample_format cpu_pmu_mem_latency_numa.PERF_SAMPLE_DATA_SRC = perf_event_sample_format.PERF_SAMPLE_DATA_SRC
PERF_SAMPLE_DATA_SRC
|
(constant) core.sys.linux.perf_event.perf_event_sample_format cpu_pmu_mem_latency_numa.PERF_SAMPLE_WEIGHT = perf_event_sample_format.PERF_SAMPLE_WEIGHT
PERF_SAMPLE_WEIGHT
;
int
(local variable) int fd
fd
= -1;
ulong
(local variable) ulong sampleType
sampleType
;
foreach (
(parameter) bool withPhys
withPhys
; [true, false])
foreach (
(local variable) int exclKernel
exclKernel
; [1, 0])
{
(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
= cast(uint)
(local variable) long pmuType
pmuType
;
(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
= 0; // ibs_op: cnt_ctl=0 (cycles), no ldlat filter
(local variable) core.sys.linux.perf_event.perf_event_attr attr
attr
.
(field) ulong core.sys.linux.perf_event.perf_event_attr.config2

extension of config1

config2
= (
(local variable) bool viaIbs
viaIbs
&&
(local variable) int exclKernel
exclKernel
) ?
(constant) ulong cpu_pmu_mem_latency_numa.run.swfilt = 1LU
swfilt
: 0;
(local variable) core.sys.linux.perf_event.perf_event_attr attr
attr
.
(field) ulong core.sys.linux.perf_event.perf_event_attr.sample_period
sample_period
= 20_000; // ibs_op min_period is 0x90
(local variable) ulong sampleType
sampleType
=
(constant) core.sys.linux.perf_event.perf_event_sample_format cpu_pmu_mem_latency_numa.run.baseType = cast(perf_event_sample_format)49161u
baseType
| (
(local variable) bool withPhys
withPhys
?
(constant) core.sys.linux.perf_event.perf_event_sample_format cpu_pmu_mem_latency_numa.PERF_SAMPLE_PHYS_ADDR = perf_event_sample_format.PERF_SAMPLE_PHYS_ADDR
PERF_SAMPLE_PHYS_ADDR
: 0);
(local variable) core.sys.linux.perf_event.perf_event_attr attr
attr
.
(field) ulong core.sys.linux.perf_event.perf_event_attr.sample_type
sample_type
=
(local variable) ulong sampleType
sampleType
;
(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
= 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
=
(local variable) int exclKernel
exclKernel
;
if (!
(local variable) bool viaIbs
viaIbs
)
(local variable) core.sys.linux.perf_event.perf_event_attr attr
attr
.
void core.sys.linux.perf_event.perf_event_attr.precise_ip(ulong v) pure nothrow @nogc @property @safe
precise_ip
=
(local variable) int maxPrecise
maxPrecise
; // cpu-PMU (Intel) fallback path
(local variable) int fd
fd
= 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, -1, 0);
if (
(local variable) int fd
fd
>= 0)
goto opened; } opened: if (
(local variable) int fd
fd
< 0)
{
void std.stdio.writefln!(char, string)(in char[] fmt, string __param_1) @safe

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

writefln
("SKIP: perf_event_open on %s failed — perf_event_paranoid, "
~ "seccomp, or unsupported sample type",
(local variable) bool viaIbs
viaIbs
? "ibs_op" : "cpu");
int core.sys.posix.sys.mman.munmap(void*, ulong) nothrow @nogc
munmap
(
(local variable) void* raw
raw
,
(constant) int cpu_pmu_mem_latency_numa.run.bufBytes = 67108864
bufBytes
);
return 0; } // ---- mmap the sample ring ------------------------------------------- enum
(constant) int cpu_pmu_mem_latency_numa.run.dataPages = 128
dataPages
= 128; // power of two
const
(local variable) const(ulong) mmapBytes
mmapBytes
= (1 +
(constant) int cpu_pmu_mem_latency_numa.run.dataPages = 128
dataPages
) *
(local variable) const(ulong) pageSize
pageSize
;
void*
(local variable) void* ring
ring
= mmap(null,
(local variable) const(ulong) mmapBytes
mmapBytes
,
(constant) int core.sys.posix.sys.mman.PROT_READ = 1
PROT_READ
|
(constant) int core.sys.posix.sys.mman.PROT_WRITE = 2
PROT_WRITE
,
(constant) int core.sys.posix.sys.mman.MAP_SHARED = 1
MAP_SHARED
,
(local variable) int fd
fd
, 0);
if (
(local variable) void* ring
ring
==
(constant) void* core.sys.posix.sys.mman.MAP_FAILED = cast(void*)cast(size_t)18446744073709551615LU
MAP_FAILED
)
{
void std.stdio.writefln!char(in char[] fmt) @safe

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

writefln
("SKIP: could not mmap the perf ring buffer");
int core.sys.posix.unistd.close(int) nothrow @nogc @trusted
close
(
(local variable) int fd
fd
);
int core.sys.posix.sys.mman.munmap(void*, ulong) nothrow @nogc
munmap
(
(local variable) void* raw
raw
,
(constant) int cpu_pmu_mem_latency_numa.run.bufBytes = 67108864
bufBytes
);
return 0; } auto
(local variable) core.sys.linux.perf_event.perf_event_mmap_page* meta
meta
= cast(
(struct) core.sys.linux.perf_event.perf_event_mmap_page

Structure of the page that can be mapped via mmap

perf_event_mmap_page
*)
(local variable) void* ring
ring
;
const
(local variable) const(ubyte*) dataStart
dataStart
= cast(const(ubyte)*)
(local variable) void* ring
ring
+
(local variable) core.sys.linux.perf_event.perf_event_mmap_page* meta
meta
.
(field) ulong core.sys.linux.perf_event.perf_event_mmap_page.data_offset

where the buffer starts

data_offset
;
const
(local variable) const(ulong) dataSize
dataSize
=
(local variable) core.sys.linux.perf_event.perf_event_mmap_page* meta
meta
.
(field) ulong core.sys.linux.perf_event.perf_event_mmap_page.data_size

data buffer size

data_size
;
// ---- sample: enable, stride, drain ---------------------------------- 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) 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;
(struct) cpu_pmu_mem_latency_numa.Sample

One decoded PERF_RECORD_SAMPLE (only the fields this probe requests).

Sample
[]
(local variable) cpu_pmu_mem_latency_numa.Sample[] samples
samples
;
ulong
(local variable) ulong totalRecords
totalRecords
,
(local variable) ulong lostRecords
lostRecords
;
void
void cpu_pmu_mem_latency_numa.run.drain() @trusted
drain
() @trusted
{ auto
(local variable) ulong head
head
=
ulong core.atomic.atomicLoad!(MemoryOrder.acq, ulong)(ref return scope shared(const(ulong)) val) pure nothrow @nogc @trusted

Loads 'val' from memory and returns it. The memory barrier specified by 'ms' is applied to the operation, which is fully sequenced by default. Valid memory orders are MemoryOrder.raw, MemoryOrder.acq, and MemoryOrder.seq.

@paramval The target variable.@returnsThe value of 'val'.
atomicLoad
!(
(enum) core.atomic.MemoryOrder

Specifies the memory ordering semantics of an atomic operation.

@see
MemoryOrder
.
(enum value) core.atomic.MemoryOrder.acq = 2

Hoist-load + hoist-store barrier. Corresponds to LLVM AtomicOrdering.Acquire and C++11/C11 memory_order_acquire.

acq
)(*cast(shared(ulong)*)&
(local variable) core.sys.linux.perf_event.perf_event_mmap_page* meta
meta
.
(field) ulong core.sys.linux.perf_event.perf_event_mmap_page.data_head

Control data for the mmap() data buffer.

User-space reading the @data_head value should issue an smp_rmb(), after reading this value.

When the mapping is PROT_WRITE the @data_tail value should be written by userspace to reflect the last read data, after issueing an smp_mb() to separate the data read from the ->data_tail store. In this case the kernel will not over-write unread data.

See perf_output_put_handle() for the data ordering.

data_{offset,size} indicate the location and size of the perf record buffer within the mmapped area.

head in the data section

data_head
);
auto
(local variable) ulong tail
tail
=
(local variable) core.sys.linux.perf_event.perf_event_mmap_page* meta
meta
.
(field) ulong core.sys.linux.perf_event.perf_event_mmap_page.data_tail

user-space written tail

data_tail
;
while (
(local variable) ulong tail
tail
<
(local variable) ulong head
head
)
{
(struct) core.sys.linux.perf_event.perf_event_header
perf_event_header
(local variable) core.sys.linux.perf_event.perf_event_header hdr
hdr
;
void cpu_pmu_mem_latency_numa.ringCopy(void* dst, const(ubyte)* dataStart, ulong dataSize, ulong logicalTail, ulong n) @system

Copies n bytes out of the perf data area at logical offset logicalTail (which may straddle the ring's wrap point) into dst.

ringCopy
(&
(local variable) core.sys.linux.perf_event.perf_event_header hdr
hdr
,
(local variable) const(ubyte*) dataStart
dataStart
,
(local variable) const(ulong) dataSize
dataSize
,
(local variable) ulong tail
tail
,
(local variable) core.sys.linux.perf_event.perf_event_header hdr
hdr
.
(constant) ulong core.sys.linux.perf_event.perf_event_header.sizeof = 8LU
sizeof
);
if (
(local variable) core.sys.linux.perf_event.perf_event_header hdr
hdr
.
(field) uint core.sys.linux.perf_event.perf_event_header.type
type
==
(enum) core.sys.linux.perf_event.perf_event_type
perf_event_type
.
(enum value) core.sys.linux.perf_event.perf_event_type.PERF_RECORD_SAMPLE = 9
struct {
   struct perf_event_header    header;

   #
   # Note that PERF_SAMPLE_IDENTIFIER duplicates PERF_SAMPLE_ID.
   # The advantage of PERF_SAMPLE_IDENTIFIER is that its position
   # is fixed relative to header.
   #

   { u64            id;      } && PERF_SAMPLE_IDENTIFIER
   { u64            ip;      } && PERF_SAMPLE_IP
   { u32            pid, tid; } && PERF_SAMPLE_TID
   { u64            time;     } && PERF_SAMPLE_TIME
   { u64            addr;     } && PERF_SAMPLE_ADDR
   { u64            id;      } && PERF_SAMPLE_ID
   { u64            stream_id;} && PERF_SAMPLE_STREAM_ID
   { u32            cpu, res; } && PERF_SAMPLE_CPU
   { u64            period;   } && PERF_SAMPLE_PERIOD

   { struct read_format    values;      } && PERF_SAMPLE_READ

   { u64            nr,
     u64            ips[nr];  } && PERF_SAMPLE_CALLCHAIN

   #
   # The RAW record below is opaque data wrt the ABI
   #
   # That is, the ABI doesn't make any promises wrt to
   # the stability of its content, it may vary depending
   # on event, hardware, kernel version and phase of
   # the moon.
   #
   # In other words, PERF_SAMPLE_RAW contents are not an ABI.
   #

   { u32            size;
     char                  data[size];}&& PERF_SAMPLE_RAW

   { u64                   nr;
       { u64 from, to, flags } lbr[nr];} && PERF_SAMPLE_BRANCH_STACK

    { u64            abi; # enum perf_sample_regs_abi
      u64            regs[weight(mask)]; } && PERF_SAMPLE_REGS_USER

    { u64            size;
      char            data[size];
      u64            dyn_size; } && PERF_SAMPLE_STACK_USER

   { u64            weight;   } && PERF_SAMPLE_WEIGHT
   { u64            data_src; } && PERF_SAMPLE_DATA_SRC
   { u64            transaction; } && PERF_SAMPLE_TRANSACTION
   { u64            abi; # enum perf_sample_regs_abi
     u64            regs[weight(mask)]; } && PERF_SAMPLE_REGS_INTR
   { u64            phys_addr;} && PERF_SAMPLE_PHYS_ADDR
};
PERF_RECORD_SAMPLE
)
{ ubyte[256]
(local variable) ubyte[256] rec
rec
;
void cpu_pmu_mem_latency_numa.ringCopy(void* dst, const(ubyte)* dataStart, ulong dataSize, ulong logicalTail, ulong n) @system

Copies n bytes out of the perf data area at logical offset logicalTail (which may straddle the ring's wrap point) into dst.

ringCopy
(
(local variable) ubyte[256] rec
rec
.
(constant) ubyte* ubyte[256].ptr = &rec
ptr
,
(local variable) const(ubyte*) dataStart
dataStart
,
(local variable) const(ulong) dataSize
dataSize
,
(local variable) ulong tail
tail
,
ushort std.algorithm.comparison.min!(ushort, ulong)(ushort __param_0, ulong __param_1) pure nothrow @nogc @safe

Iterates the passed arguments and returns the minimum value.

@paramargs The values to select the minimum from. At least two arguments must be passed, and they must be comparable with <.@returnsThe minimum of the passed-in values. The type of the returned value is the type among the passed arguments that is able to store the smallest value. If at least one of the arguments is NaN, the result is an unspecified value. See minElement for examples on how to cope with NaNs.@seeminElement
min
(
(local variable) core.sys.linux.perf_event.perf_event_header hdr
hdr
.
(field) ushort core.sys.linux.perf_event.perf_event_header.size
size
,
(local variable) ubyte[256] rec
rec
.
(constant) ulong ubyte[256].length = 256LU
length
));
(alias) object.size_t = ulong
size_t
(local variable) ulong cur
cur
=
(local variable) core.sys.linux.perf_event.perf_event_header hdr
hdr
.
(constant) ulong core.sys.linux.perf_event.perf_event_header.sizeof = 8LU
sizeof
;
ulong
ulong cpu_pmu_mem_latency_numa.run.drain.take() pure nothrow @nogc @system
take
() { const
(local variable) const(ulong) v
v
= *cast(ulong*)(
(local variable) ubyte[256] rec
rec
.
(constant) ubyte* ubyte[256].ptr = &rec
ptr
+
(local variable) ulong cur
cur
);
(local variable) ulong cur
cur
+= 8; return
(local variable) const(ulong) v
v
; }
(struct) cpu_pmu_mem_latency_numa.Sample

One decoded PERF_RECORD_SAMPLE (only the fields this probe requests).

Sample
(local variable) cpu_pmu_mem_latency_numa.Sample s
s
;
if (
(local variable) ulong sampleType
sampleType
&
(constant) core.sys.linux.perf_event.perf_event_sample_format cpu_pmu_mem_latency_numa.PERF_SAMPLE_IP = perf_event_sample_format.PERF_SAMPLE_IP
PERF_SAMPLE_IP
)
(local variable) cpu_pmu_mem_latency_numa.Sample s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.ip
ip
=
ulong cpu_pmu_mem_latency_numa.run.drain.take() pure nothrow @nogc @system
take
();
if (
(local variable) ulong sampleType
sampleType
&
(constant) core.sys.linux.perf_event.perf_event_sample_format cpu_pmu_mem_latency_numa.PERF_SAMPLE_ADDR = perf_event_sample_format.PERF_SAMPLE_ADDR
PERF_SAMPLE_ADDR
)
(local variable) cpu_pmu_mem_latency_numa.Sample s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.addr
addr
=
ulong cpu_pmu_mem_latency_numa.run.drain.take() pure nothrow @nogc @system
take
();
if (
(local variable) ulong sampleType
sampleType
&
(constant) core.sys.linux.perf_event.perf_event_sample_format cpu_pmu_mem_latency_numa.PERF_SAMPLE_WEIGHT = perf_event_sample_format.PERF_SAMPLE_WEIGHT
PERF_SAMPLE_WEIGHT
)
(local variable) cpu_pmu_mem_latency_numa.Sample s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.weight
weight
=
ulong cpu_pmu_mem_latency_numa.run.drain.take() pure nothrow @nogc @system
take
();
if (
(local variable) ulong sampleType
sampleType
&
(constant) core.sys.linux.perf_event.perf_event_sample_format cpu_pmu_mem_latency_numa.PERF_SAMPLE_DATA_SRC = perf_event_sample_format.PERF_SAMPLE_DATA_SRC
PERF_SAMPLE_DATA_SRC
)
(local variable) cpu_pmu_mem_latency_numa.Sample s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.dataSrc
dataSrc
=
ulong cpu_pmu_mem_latency_numa.run.drain.take() pure nothrow @nogc @system
take
();
if (
(local variable) ulong sampleType
sampleType
&
(constant) core.sys.linux.perf_event.perf_event_sample_format cpu_pmu_mem_latency_numa.PERF_SAMPLE_PHYS_ADDR = perf_event_sample_format.PERF_SAMPLE_PHYS_ADDR
PERF_SAMPLE_PHYS_ADDR
)
(local variable) cpu_pmu_mem_latency_numa.Sample s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.physAddr
physAddr
=
ulong cpu_pmu_mem_latency_numa.run.drain.take() pure nothrow @nogc @system
take
();
(local variable) cpu_pmu_mem_latency_numa.Sample[] samples
samples
~=
(local variable) cpu_pmu_mem_latency_numa.Sample s
s
;
(local variable) ulong totalRecords
totalRecords
++;
} else if (
(local variable) core.sys.linux.perf_event.perf_event_header hdr
hdr
.
(field) uint core.sys.linux.perf_event.perf_event_header.type
type
==
(enum) core.sys.linux.perf_event.perf_event_type
perf_event_type
.
(enum value) core.sys.linux.perf_event.perf_event_type.PERF_RECORD_LOST = 2
struct {
   struct perf_event_header    header;
   u64                id;
   u64                lost;
    struct sample_id        sample_id;
};
PERF_RECORD_LOST
)
(local variable) ulong lostRecords
lostRecords
++;
(local variable) ulong tail
tail
+=
(local variable) core.sys.linux.perf_event.perf_event_header hdr
hdr
.
(field) ushort core.sys.linux.perf_event.perf_event_header.size
size
;
}
void core.atomic.atomicStore!(MemoryOrder.rel, ulong, ulong)(ref shared(ulong) val, ulong newval) pure nothrow @nogc @trusted

Writes 'newval' into 'val'. The memory barrier specified by 'ms' is applied to the operation, which is fully sequenced by default. Valid memory orders are MemoryOrder.raw, MemoryOrder.rel, and MemoryOrder.seq.

@paramval The target variable.@paramnewval The value to store.
atomicStore
!(
(enum) core.atomic.MemoryOrder

Specifies the memory ordering semantics of an atomic operation.

@see
MemoryOrder
.
(enum value) core.atomic.MemoryOrder.rel = 3

Sink-load + sink-store barrier. Corresponds to LLVM AtomicOrdering.Release and C++11/C11 memory_order_release.

rel
)(*cast(shared(ulong)*)&
(local variable) core.sys.linux.perf_event.perf_event_mmap_page* meta
meta
.
(field) ulong core.sys.linux.perf_event.perf_event_mmap_page.data_tail

user-space written tail

data_tail
,
(local variable) ulong head
head
);
}
int core.sys.posix.sys.ioctl.ioctl(int __fd, ulong __request, ...) nothrow @nogc
ioctl
(
(local variable) int fd
fd
, cast(c_ulong)
(constant) int core.sys.linux.perf_event.PERF_EVENT_IOC_RESET = 9219
PERF_EVENT_IOC_RESET
, 0);
int core.sys.posix.sys.ioctl.ioctl(int __fd, ulong __request, ...) nothrow @nogc
ioctl
(
(local variable) int fd
fd
, cast(c_ulong)
(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
, 0);
(alias) object.size_t = ulong
size_t
(local variable) ulong pos
pos
;
foreach (
(local variable) int pass
pass
; 0 .. 200)
{
(local variable) ulong pos
pos
=
ulong cpu_pmu_mem_latency_numa.chase(const(ulong[]) words, ulong start, ulong steps) @safe

steps dependent chases from start; returns the landing index (folded into a _gshared sink by the caller so the loads survive DCE).

chase
(
(local variable) ulong[] words
words
,
(local variable) ulong pos
pos
, 100_000);
(__gshared global) ulong cpu_pmu_mem_latency_numa.sink
sink
+=
(local variable) ulong pos
pos
;
void cpu_pmu_mem_latency_numa.run.drain() @trusted
drain
();
if (
(local variable) cpu_pmu_mem_latency_numa.Sample[] samples
samples
.
(field) ulong cpu_pmu_mem_latency_numa.Sample[].length
length
>= 4000)
break; }
int core.sys.posix.sys.ioctl.ioctl(int __fd, ulong __request, ...) nothrow @nogc
ioctl
(
(local variable) int fd
fd
, cast(c_ulong)
(constant) int core.sys.linux.perf_event.PERF_EVENT_IOC_DISABLE = 9217
PERF_EVENT_IOC_DISABLE
, 0);
void cpu_pmu_mem_latency_numa.run.drain() @trusted
drain
();
int core.sys.posix.sys.mman.munmap(void*, ulong) nothrow @nogc
munmap
(
(local variable) void* ring
ring
,
(local variable) const(ulong) mmapBytes
mmapBytes
);
int core.sys.posix.unistd.close(int) nothrow @nogc @trusted
close
(
(local variable) int fd
fd
);
// ---- report ---------------------------------------------------------
void std.stdio.writefln!(char, string)(in char[] fmt, string __param_1) @safe

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

writefln
("== precise memory-access sampling: %s ==",
(local variable) bool viaIbs
viaIbs
? (
(local variable) const(bool) zen4
zen4
? "AMD IBS (ibs_op, zen4_ibs_extensions)" : "AMD IBS (ibs_op)")
: "cpu PMU precise_ip (Intel PEBS path — UNVERIFIED on this host)");
void std.stdio.writefln!(char, long, string)(in char[] fmt, long __param_1, string __param_2) @safe

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

writefln
(" PMU type=%d period=20000 sample_type=IP|ADDR|DATA_SRC|WEIGHT%s",
(local variable) long pmuType
pmuType
, (
(local variable) ulong sampleType
sampleType
&
(constant) core.sys.linux.perf_event.perf_event_sample_format cpu_pmu_mem_latency_numa.PERF_SAMPLE_PHYS_ADDR = perf_event_sample_format.PERF_SAMPLE_PHYS_ADDR
PERF_SAMPLE_PHYS_ADDR
) ? "|PHYS_ADDR" : "");
void std.stdio.writefln!(char, int, const(int), int)(in char[] fmt, int __param_1, const(int) __param_2, int __param_3) @safe

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

writefln
(" workload=%d MiB home node(get_mempolicy)=%d NUMA nodes online=%d",
(constant) int cpu_pmu_mem_latency_numa.run.bufBytes = 67108864
bufBytes
>> 20,
(local variable) const(int) homeNode
homeNode
,
(local variable) int nodesOnline
nodesOnline
);
if (
(local variable) int nodesOnline
nodesOnline
<= 1)
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
(" (single-node host: node round-trip is demonstrated; cross-node "
~ "classification is not — that needs a multi-socket box)"); // Keep only samples with a resolved data address (IBS sets ADDR only when // DcLinAddrValid). Classify each such address to a node, both ways. struct
(struct) cpu_pmu_mem_latency_numa.run.Row
Row
{
(struct) cpu_pmu_mem_latency_numa.Sample

One decoded PERF_RECORD_SAMPLE (only the fields this probe requests).

Sample
(field) cpu_pmu_mem_latency_numa.Sample cpu_pmu_mem_latency_numa.run.Row.s
s
; int
(field) int cpu_pmu_mem_latency_numa.run.Row.nGmp
nGmp
,
(field) int cpu_pmu_mem_latency_numa.run.Row.nMvp
nMvp
; }
(struct) cpu_pmu_mem_latency_numa.run.Row
Row
[]
(local variable) cpu_pmu_mem_latency_numa.run.Row[] rows
rows
;
foreach (
(parameter) cpu_pmu_mem_latency_numa.Sample s
s
;
(local variable) cpu_pmu_mem_latency_numa.Sample[] samples
samples
)
if (
(local variable) cpu_pmu_mem_latency_numa.Sample s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.addr
addr
!= 0 &&
string cpu_pmu_mem_latency_numa.memOpStr(ulong ds) pure nothrow @nogc @safe
memOpStr
(
(local variable) cpu_pmu_mem_latency_numa.Sample s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.dataSrc
dataSrc
) != "N/A")
(local variable) cpu_pmu_mem_latency_numa.run.Row[] rows
rows
~=
(struct) cpu_pmu_mem_latency_numa.run.Row
Row
(
(local variable) cpu_pmu_mem_latency_numa.Sample s
s
,
int cpu_pmu_mem_latency_numa.nodeViaGetMempolicy(void* addr) nothrow @nogc @trusted

Node of the page containing addr, or a negative -errno, via get_mempolicy(MPOL_F_NODE | MPOL_F_ADDR). numaif.h: long get_mempolicy(int *mode, ulong nmask, ulong maxnode, void addr, ulong flags); with these flags, mode receives the node number.

nodeViaGetMempolicy
(cast(void*)
(local variable) cpu_pmu_mem_latency_numa.Sample s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.addr
addr
),
int cpu_pmu_mem_latency_numa.nodeViaMovePages(void* addr, ulong pageSize) nothrow @nogc @trusted

Node of the page containing addr via move_pages() query mode (nodes == NULL). numaif.h: long move_pages(int pid, ulong count, void **pages, const int nodes, int status, int flags); status[0] receives the node number (or a negative -errno).

nodeViaMovePages
(cast(void*)
(local variable) cpu_pmu_mem_latency_numa.Sample s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.addr
addr
,
(local variable) const(ulong) pageSize
pageSize
));
if (
(local variable) cpu_pmu_mem_latency_numa.run.Row[] rows
rows
.
(field) ulong cpu_pmu_mem_latency_numa.run.Row[].length
length
== 0)
{
void std.stdio.writefln!(char, ulong, ulong)(in char[] fmt, ulong __param_1, ulong __param_2) @safe

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

writefln
(" collected %d raw samples, %d with a usable data address — "
~ "reduced output (no per-address rows to show)",
(local variable) cpu_pmu_mem_latency_numa.Sample[] samples
samples
.
(field) ulong cpu_pmu_mem_latency_numa.Sample[].length
length
,
(local variable) cpu_pmu_mem_latency_numa.run.Row[] rows
rows
.
(field) ulong cpu_pmu_mem_latency_numa.run.Row[].length
length
);
int core.sys.posix.sys.mman.munmap(void*, ulong) nothrow @nogc
munmap
(
(local variable) void* raw
raw
,
(constant) int cpu_pmu_mem_latency_numa.run.bufBytes = 67108864
bufBytes
);
return 0; } // Lead with samples that missed the L1 — those exercise the whole // data-source/latency path; pad with L1 hits if there are few.
(struct) cpu_pmu_mem_latency_numa.run.Row
Row
[]
(local variable) cpu_pmu_mem_latency_numa.run.Row[] show
show
;
foreach (
(parameter) cpu_pmu_mem_latency_numa.run.Row r
r
;
(local variable) cpu_pmu_mem_latency_numa.run.Row[] rows
rows
)
if (
string cpu_pmu_mem_latency_numa.memLvlStr(ulong ds) nothrow @safe
memLvlStr
(
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) cpu_pmu_mem_latency_numa.Sample cpu_pmu_mem_latency_numa.run.Row.s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.dataSrc
dataSrc
) != "L1 hit" &&
(local variable) cpu_pmu_mem_latency_numa.run.Row[] show
show
.
(field) ulong cpu_pmu_mem_latency_numa.run.Row[].length
length
< 8)
(local variable) cpu_pmu_mem_latency_numa.run.Row[] show
show
~=
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
;
foreach (
(parameter) cpu_pmu_mem_latency_numa.run.Row r
r
;
(local variable) cpu_pmu_mem_latency_numa.run.Row[] rows
rows
)
if (
(local variable) cpu_pmu_mem_latency_numa.run.Row[] show
show
.
(field) ulong cpu_pmu_mem_latency_numa.run.Row[].length
length
< 8)
(local variable) cpu_pmu_mem_latency_numa.run.Row[] show
show
~=
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
;
void std.stdio.writefln!(char, ulong, ulong)(in char[] fmt, ulong __param_1, ulong __param_2) @safe

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

writefln
("\n sampled data accesses (%d of %d; cache-miss samples first):",
(local variable) cpu_pmu_mem_latency_numa.run.Row[] show
show
.
(field) ulong cpu_pmu_mem_latency_numa.run.Row[].length
length
,
(local variable) cpu_pmu_mem_latency_numa.run.Row[] rows
rows
.
(field) ulong cpu_pmu_mem_latency_numa.run.Row[].length
length
);
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
(" ip addr op level "
~ "snoop tlb lat node[gmp/mvp]"); foreach (
(parameter) cpu_pmu_mem_latency_numa.run.Row r
r
;
(local variable) cpu_pmu_mem_latency_numa.run.Row[] show
show
)
void std.stdio.writefln!(char, ulong, ulong, string, string, string, string, ulong, int, int)(in char[] fmt, ulong __param_1, ulong __param_2, string __param_3, string __param_4, string __param_5, string __param_6, ulong __param_7, int __param_8, int __param_9) @safe

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

writefln
(" 0x%016x 0x%016x %-6s %-18s %-6s %-8s %4d %d/%d",
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) cpu_pmu_mem_latency_numa.Sample cpu_pmu_mem_latency_numa.run.Row.s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.ip
ip
,
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) cpu_pmu_mem_latency_numa.Sample cpu_pmu_mem_latency_numa.run.Row.s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.addr
addr
,
string cpu_pmu_mem_latency_numa.memOpStr(ulong ds) pure nothrow @nogc @safe
memOpStr
(
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) cpu_pmu_mem_latency_numa.Sample cpu_pmu_mem_latency_numa.run.Row.s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.dataSrc
dataSrc
),
string cpu_pmu_mem_latency_numa.memLvlStr(ulong ds) nothrow @safe
memLvlStr
(
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) cpu_pmu_mem_latency_numa.Sample cpu_pmu_mem_latency_numa.run.Row.s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.dataSrc
dataSrc
),
string cpu_pmu_mem_latency_numa.snoopStr(ulong ds) pure nothrow @nogc @safe
snoopStr
(
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) cpu_pmu_mem_latency_numa.Sample cpu_pmu_mem_latency_numa.run.Row.s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.dataSrc
dataSrc
),
string cpu_pmu_mem_latency_numa.tlbStr(ulong ds) pure nothrow @safe
tlbStr
(
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) cpu_pmu_mem_latency_numa.Sample cpu_pmu_mem_latency_numa.run.Row.s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.dataSrc
dataSrc
),
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) cpu_pmu_mem_latency_numa.Sample cpu_pmu_mem_latency_numa.run.Row.s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.weight
weight
,
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) int cpu_pmu_mem_latency_numa.run.Row.nGmp
nGmp
,
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) int cpu_pmu_mem_latency_numa.run.Row.nMvp
nMvp
);
// Level histogram + node-agreement summary. ulong[
(alias) object.string = string
string
]
(local variable) ulong[string] lvlHist
lvlHist
;
int
(local variable) int agreeHome
agreeHome
,
(local variable) int disagree
disagree
,
(local variable) int gmpErr
gmpErr
,
(local variable) int mvpErr
mvpErr
;
ulong[]
(local variable) ulong[] lats
lats
;
foreach (
(parameter) cpu_pmu_mem_latency_numa.run.Row r
r
;
(local variable) cpu_pmu_mem_latency_numa.run.Row[] rows
rows
)
{
ulong* core.internal.newaa._d_aaGetY!(string, ulong, ulong[string], string, ulong, string)(ref scope ulong[string] aa, string key, out bool found) pure nothrow @safe

Lookup key in aa. Called only from implementation of (aakey) expressions when value is mutable.

@paramaa associative array@paramkey reference to the key value@paramfound returns whether the key was found or a new entry was added@returnsif key was in the aa, a mutable pointer to the existing value. If key was not in the aa, a mutable pointer to newly inserted value which is set to zero
lvlHist
[
string cpu_pmu_mem_latency_numa.memLvlStr(ulong ds) nothrow @safe
memLvlStr
(
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) cpu_pmu_mem_latency_numa.Sample cpu_pmu_mem_latency_numa.run.Row.s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.dataSrc
dataSrc
)]++;
if (
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) int cpu_pmu_mem_latency_numa.run.Row.nGmp
nGmp
< 0)
(local variable) int gmpErr
gmpErr
++;
if (
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) int cpu_pmu_mem_latency_numa.run.Row.nMvp
nMvp
< 0)
(local variable) int mvpErr
mvpErr
++;
if (
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) int cpu_pmu_mem_latency_numa.run.Row.nGmp
nGmp
>= 0 &&
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) int cpu_pmu_mem_latency_numa.run.Row.nMvp
nMvp
>= 0)
{ if (
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) int cpu_pmu_mem_latency_numa.run.Row.nGmp
nGmp
==
(local variable) const(int) homeNode
homeNode
&&
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) int cpu_pmu_mem_latency_numa.run.Row.nMvp
nMvp
==
(local variable) const(int) homeNode
homeNode
)
(local variable) int agreeHome
agreeHome
++;
else
(local variable) int disagree
disagree
++;
} if (
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) cpu_pmu_mem_latency_numa.Sample cpu_pmu_mem_latency_numa.run.Row.s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.weight
weight
> 0)
(local variable) ulong[] lats
lats
~=
(local variable) cpu_pmu_mem_latency_numa.run.Row r
r
.
(field) cpu_pmu_mem_latency_numa.Sample cpu_pmu_mem_latency_numa.run.Row.s
s
.
(field) ulong cpu_pmu_mem_latency_numa.Sample.weight
weight
;
}
void std.stdio.writefln!(char, ulong)(in char[] fmt, ulong __param_1) @safe

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

writefln
("\n data-source levels across %d resolved samples:",
(local variable) cpu_pmu_mem_latency_numa.run.Row[] rows
rows
.
(field) ulong cpu_pmu_mem_latency_numa.run.Row[].length
length
);
foreach (
int core.internal.newaa._d_aaApply2!(string, ulong, int delegate(ref string, ref ulong) @safe)(inout(ulong[string]) a, int delegate(ref string, ref ulong) @safe dg) @safe

foreach opApply over all key/value pairs

Note

emulated by the compiler during CTFE

k
,
(parameter) ulong v
v
;
(local variable) ulong[string] lvlHist
lvlHist
)
void std.stdio.writefln!(char, string, ulong)(in char[] fmt, string __param_1, ulong __param_2) @safe

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

writefln
(" %-24s %d",
(local variable) string k
k
,
(local variable) ulong v
v
);
void std.stdio.writefln!(char, int, const(int), int, int, int)(in char[] fmt, int __param_1, const(int) __param_2, int __param_3, int __param_4, int __param_5) @safe

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

writefln
(" node classification: %d on home node %d (get_mempolicy == move_pages), "
~ "%d elsewhere; gmp errors=%d, mvp errors=%d",
(local variable) int agreeHome
agreeHome
,
(local variable) const(int) homeNode
homeNode
,
(local variable) int disagree
disagree
,
(local variable) int gmpErr
gmpErr
,
(local variable) int mvpErr
mvpErr
);
if (
(local variable) ulong[] lats
lats
.
(field) ulong ulong[].length
length
)
{
(local variable) ulong[] lats
lats
.
std.range.SortedRange!(ulong[], "a < b", SortedRangeOptions.assumeSorted) std.algorithm.sorting.sort!("a < b", SwapStrategy.unstable, ulong[])(ulong[] r) pure nothrow @nogc @safe

Sorts a random-access range according to the predicate less.

Performs O(r.length * log(r.length)) evaluations of less. If less involves expensive computations on the sort key, it may be worthwhile to use schwartzSort instead.

Stable sorting requires hasAssignableElements!Range to be true.

sort returns a SortedRange over the original range, allowing functions that can take advantage of sorted data to know that the range is sorted and adjust accordingly. The SortedRange is a wrapper around the original range, so both it and the original range are sorted. Other functions can't know that the original range has been sorted, but they can know that SortedRange has been sorted.

Preconditions

The predicate is expected to satisfy certain rules in order for sort to behave as expected - otherwise, the program may fail on certain inputs (but not others) when not compiled in release mode, due to the cursory assumeSorted check. Specifically, sort expects less(a,b) && less(b,c) to imply less(a,c) (transitivity), and, conversely, !less(a,b) && !less(b,c) to imply !less(a,c). Note that the default predicate ("a < b") does not always satisfy these conditions for floating point types, because the expression will always be false when either a or b is NaN. Use cmp instead.

Algorithms

Introsort is used for unstable sorting and Timsort is used for stable sorting. Each algorithm has benefits beyond stability. Introsort is generally faster but Timsort may achieve greater speeds on data with low entropy or if predicate calls are expensive. Introsort performs no allocations whereas Timsort will perform one or more allocations per call. Both algorithms have O(n log n) worst-case time complexity.

Examples

int[] array = [ 1, 2, 3, 4 ];

// sort in descending order
array.sort!("a > b");
assert(array == [ 4, 3, 2, 1 ]);

// sort in ascending order
array.sort();
assert(array == [ 1, 2, 3, 4 ]);

// sort with reusable comparator and chain
alias myComp = (x, y) => x > y;
assert(array.sort!(myComp).release == [ 4, 3, 2, 1 ]);
// Showcase stable sorting
import std.algorithm.mutation : SwapStrategy;
string[] words = [ "aBc", "a", "abc", "b", "ABC", "c" ];
sort!("toUpper(a) < toUpper(b)", SwapStrategy.stable)(words);
assert(words == [ "a", "aBc", "abc", "ABC", "b", "c" ]);
// Sorting floating-point numbers in presence of NaN
double[] numbers = [-0.0, 3.0, -2.0, double.nan, 0.0, -double.nan];

import std.algorithm.comparison : equal;
import std.math.operations : cmp;
import std.math.traits : isIdentical;

sort!((a, b) => cmp(a, b) < 0)(numbers);

double[] sorted = [-double.nan, -2.0, -0.0, 0.0, 3.0, double.nan];
assert(numbers.equal!isIdentical(sorted));
@paramless The predicate to sort by.@paramss The swapping strategy to use.@paramr The range to sort.@returnsThe initial range wrapped as a SortedRange with the predicate binaryFun!less.@see

assumeSorted

SortedRange

SwapStrategy

binaryFun

sort
();
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
(" DC-miss latency (WEIGHT) on %d load samples: min=%d median=%d max=%d cycles",
(local variable) ulong[] lats
lats
.
(field) ulong ulong[].length
length
,
(local variable) ulong[] lats
lats
[0],
(local variable) ulong[] lats
lats
[$ / 2],
(local variable) ulong[] lats
lats
[$ - 1]);
} else
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
(" DC-miss latency (WEIGHT): none — no sampled load missed the data cache");
int core.sys.posix.sys.mman.munmap(void*, ulong) nothrow @nogc
munmap
(
(local variable) void* raw
raw
,
(constant) int cpu_pmu_mem_latency_numa.run.bufBytes = 67108864
bufBytes
);
return 0; } } int
int D main()
main
()
{ version (
linux
linux
)
return
int cpu_pmu_mem_latency_numa.run()
run
();
else { import std.stdio : writefln; writefln("SKIP: perf_event_open / IBS is Linux-only"); return 0; } }