Skip to content
Closed

test #58

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/perf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ jobs:
build_with_profile head
deactivate

# The vibe.d workload is pinned by dub.selections.json, so a cache hit
# keeps the package registry out of the loop on all but the first run.
- name: Cache vibe.d workload sources
uses: actions/cache@v4
with:
path: ~/.dub/packages
key: dub-${{ hashFiles('tools/perfrunner/workloads/vibed/dub.selections.json') }}

- name: Measure
run: |
set -uexo pipefail
Expand Down
3 changes: 3 additions & 0 deletions tools/perfrunner/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ perfrunner.exe
*.o
*.obj
results.json

# The workload's dependency pin has to be tracked, the repo root ignores it.
!workloads/vibed/dub.selections.json
18 changes: 14 additions & 4 deletions tools/perfrunner/source/app.d
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,16 @@ import std.stdio : stderr, writeln;

import metrics : measure, initials;
import report : MetricResult, render, Report;
import vibed : describeFlags;

// Initial workload: the one source file compile to measure DMD.
enum workload = buildPath(__FILE_FULL_PATH__.dirName.dirName, "workloads", "hello.d");
enum workloads = buildPath(__FILE_FULL_PATH__.dirName.dirName, "workloads");

// The one source file compile to measure DMD.
enum workload = buildPath(workloads, "hello.d");

// Third-party workload: its sources are fetched by dub, the recipe is pinned in-repo.
enum vibedDir = buildPath(workloads, "vibed");
enum vibedRoot = buildPath(vibedDir, "source", "app.d");

version (unittest) {} else
int main(string[] args)
Expand Down Expand Up @@ -50,8 +57,11 @@ int main(string[] args)
auto tmp = buildPath(tempDir, "perfrunner");
mkdirRecurse(tmp);

auto base = measure(baseDmd, workload, basePhobos, tmp, "base");
auto head = measure(headDmd, workload, headPhobos, tmp, "head");
// Resolved once: both refs have to compile vibe.d with the same flags.
auto vibedFlags = describeFlags(vibedDir, baseDmd);

auto base = measure(baseDmd, workload, basePhobos, vibedRoot, vibedFlags, tmp, "base");
auto head = measure(headDmd, workload, headPhobos, vibedRoot, vibedFlags, tmp, "head");

MetricResult[] metrics;
foreach (def; initials)
Expand Down
10 changes: 9 additions & 1 deletion tools/perfrunner/source/metrics.d
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,34 @@ immutable MetricDef[] initials = [
MetricDef("compile_hello_debug_instr", "compile hello.d (instr)", "count", "cachegrind"),
MetricDef("compile_hello_release_instr", "compile hello.d -O (instr)", "count", "cachegrind"),
MetricDef("compile_phobos_instr", "compile Phobos (instr)", "count", "cachegrind"),
MetricDef("compile_vibed_instr", "compile vibe.d (instr)", "count", "cachegrind"),
MetricDef("dmd_binary_size", "dmd binary size (stripped)", "bytes", "stat"),
MetricDef("hello_binary_size", "hello binary size", "bytes", "stat"),
MetricDef("hello_max_rss", "peak RSS (compile hello.d)", "kb", "time -v"),
MetricDef("phobos_max_rss", "peak RSS (compile Phobos)", "kb", "time -v"),
MetricDef("vibed_max_rss", "peak RSS (compile vibe.d)", "kb", "time -v"),
];

// Measure every metric for one dmd binary. `tag` ("base"/"head")
// keeps the two runs' temp files apart
long[string] measure(string dmd, string workload, string phobos, string tmp, string tag)
long[string] measure(string dmd, string workload, string phobos,
string vibed, string[] vibedFlags, string tmp, string tag)
{
auto stdPackage = buildPath(phobos, "std", "package.d");
auto phobosFlags = ["-i=std", "-preview=dip1000"];
// Unlike a dub build, which compiles one package per invocation, this pulls
// the whole vibe.d tree into a single compile.
auto vibeFlags = "-i" ~ vibedFlags;
return [
"compile_hello_debug_instr": instructions(dmd, [], workload, tmp, tag ~ "-dbg"),
"compile_hello_release_instr": instructions(dmd, ["-O", "-release"], workload, tmp, tag ~ "-rel"),
"compile_phobos_instr": instructions(dmd, phobosFlags, stdPackage, tmp, tag ~ "-phobos"),
"compile_vibed_instr": instructions(dmd, vibeFlags, vibed, tmp, tag ~ "-vibed"),
"dmd_binary_size": strippedSize(dmd, buildPath(tmp, tag ~ "-dmd")),
"hello_binary_size": helloSize(dmd, workload, tmp, tag),
"hello_max_rss": maxRss(dmd, [], workload, tmp, tag),
"phobos_max_rss": maxRss(dmd, phobosFlags, stdPackage, tmp, tag ~ "-phobos"),
"vibed_max_rss": maxRss(dmd, vibeFlags, vibed, tmp, tag ~ "-vibed"),
];
}

Expand Down
58 changes: 58 additions & 0 deletions tools/perfrunner/source/vibed.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
module vibed;

import std.process : execute;

// The flags dub would pass to the compiler for the vibe.d workload: the
// -version=Have_* set and the import paths of all pinned dependencies.
// Called once, so base and head compile with an identical command line.
string[] describeFlags(string dir, string dmd)
{
auto r = execute(["dub", "describe", "--root=" ~ dir, "--compiler=" ~ dmd,
"--data=versions,import-paths,string-import-paths"]);
if (r.status != 0)
throw new Exception("dub describe failed:\n" ~ r.output);
return splitFlags(r.output);
}

// dub quotes any flag holding a space, so splitting on whitespace is not enough.
string[] splitFlags(string output)
{
string[] flags;
char[] flag;
bool quoted, started;

foreach (c; output)
{
if (c == '\'')
quoted = !quoted;
else if (!quoted && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
{
if (started)
flags ~= flag.idup;
flag.length = 0;
started = false;
continue;
}
else
flag ~= c;
started = true;
}

if (started)
flags ~= flag.idup;
return flags;
}

unittest
{
auto sample = "-version=Have_vibe_d -version=EventcoreEpollDriver "
~ "'-I/home/me/my dub/packages/vibe-d/0.10.3/vibe-d/source/' "
~ "-I/home/me/.dub/packages/eventcore/0.9.39/eventcore/source/\n";

assert(splitFlags(sample) == [
"-version=Have_vibe_d",
"-version=EventcoreEpollDriver",
"-I/home/me/my dub/packages/vibe-d/0.10.3/vibe-d/source/",
"-I/home/me/.dub/packages/eventcore/0.9.39/eventcore/source/",
]);
}
8 changes: 8 additions & 0 deletions tools/perfrunner/workloads/vibed/dub.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "vibed-workload",
"description": "vibe.d compile workload for perfrunner",
"targetType": "executable",
"dependencies": {
"vibe-d": "0.10.3"
}
}
21 changes: 21 additions & 0 deletions tools/perfrunner/workloads/vibed/dub.selections.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"fileVersion": 1,
"versions": {
"diet-ng": "1.8.4",
"during": "0.3.0",
"eventcore": "0.9.39",
"mir-linux-kernel": "1.2.1",
"openssl": "3.4.0",
"openssl-static": "1.0.5+3.0.8",
"silly": "1.1.1",
"stdx-allocator": "2.77.5",
"taggedalgebraic": "1.0.1",
"vibe-container": "1.7.1",
"vibe-core": "2.14.0",
"vibe-d": "0.10.3",
"vibe-http": "1.5.1",
"vibe-inet": "1.3.1",
"vibe-serialization": "1.2.0",
"vibe-stream": "1.4.1"
}
}
5 changes: 5 additions & 0 deletions tools/perfrunner/workloads/vibed/source/app.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import vibe.vibe;

void main()
{
}
Loading