Skip to content

Commit

Permalink
feat: add benchmarking support to swingset-runner
Browse files Browse the repository at this point in the history
  • Loading branch information
FUDCo committed Jun 15, 2020
1 parent 07a51cd commit 19a4ef7
Show file tree
Hide file tree
Showing 7 changed files with 318 additions and 19 deletions.
37 changes: 37 additions & 0 deletions packages/swingset-runner/demo/pingPongBenchmark/bootstrap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import harden from '@agoric/harden';

console.log(`=> loading bootstrap.js`);

export default function setup(syscall, state, helpers) {
function log(what) {
helpers.log(what);
console.log(what);
}
log(`=> setup called`);
let alice;
let bob;
return helpers.makeLiveSlots(
syscall,
state,
E =>
harden({
bootstrap(argv, vats) {
alice = vats.alice;
bob = vats.bob;
console.log('=> bootstrap() called');
E(alice).setNickname('alice');
E(bob).setNickname('bob');
E(alice)
.introduceYourselfTo(bob)
.then(
r => log(`=> alice.introduceYourselfTo(bob) resolved to '${r}'`),
e => log(`=> alice.introduceYourselfTo(bob) rejected as '${e}'`),
);
},
runBenchmarkRound() {
E(alice).doPing('hey!');
},
}),
helpers.vatID,
);
}
48 changes: 48 additions & 0 deletions packages/swingset-runner/demo/pingPongBenchmark/vat-alice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import harden from '@agoric/harden';

function build(E, log) {
let myNickname;
let otherNickname = 'unknown';
let otherContact = null;

function makeContact() {
return harden({
myNameIs(nickname) {
otherNickname = nickname;
log(`${myNickname}: contact is now named ${otherNickname}`);
},
pong(tag, ponger) {
log(`${myNickname}: ponged with "${tag}" by ${ponger}`);
},
});
}

return harden({
setNickname(nickname) {
myNickname = nickname;
},
introduceYourselfTo(other) {
log(`${myNickname}.introduce`);
const myContact = makeContact();
otherContact = E(other).hello(myContact, myNickname);
return `${myNickname} setup done\n${myNickname} vat is happy\n`;
},
doPing(tag) {
log(`${myNickname}: pings ${otherNickname} with ${tag}`);
E(otherContact).ping(tag);
},
});
}

export default function setup(syscall, state, helpers) {
function log(what) {
helpers.log(what);
console.log(what);
}
return helpers.makeLiveSlots(
syscall,
state,
E => build(E, log),
helpers.vatID,
);
}
39 changes: 39 additions & 0 deletions packages/swingset-runner/demo/pingPongBenchmark/vat-bob.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import harden from '@agoric/harden';

function build(E, log) {
let myNickname;

function makeContact(otherContact, otherNickname) {
return harden({
ping(tag) {
log(`${myNickname}: pinged with "${tag}", ponging ${otherNickname}`);
E(otherContact).pong(tag, myNickname);
},
});
}

return harden({
setNickname(nickname) {
myNickname = nickname;
},
hello(otherContact, otherNickname) {
const myContact = makeContact(otherContact, otherNickname);
E(otherContact).myNameIs(myNickname);
log(`${myNickname}.hello sees ${otherNickname}`);
return myContact;
},
});
}

export default function setup(syscall, state, helpers) {
function log(what) {
helpers.log(what);
console.log(what);
}
return helpers.makeLiveSlots(
syscall,
state,
E => build(E, log),
helpers.vatID,
);
}
44 changes: 44 additions & 0 deletions packages/swingset-runner/demo/promiseChainBenchmark/bootstrap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import harden from '@agoric/harden';

console.log(`=> loading bootstrap.js`);

function build(E, log) {
let bob;
let p;
function waitForNextResolution() {
p.then(
answer => {
log(`Alice: Bob answers with value ${answer[0]}`);
p = answer[1];
E(bob).gen();
},
err => {
log(`=> Alice: Bob rejected, ${err}`);
},
);
}

return {
bootstrap(argv, vats) {
bob = vats.bob;
p = E(bob).init();
E(bob).gen();
},
runBenchmarkRound() {
waitForNextResolution();
},
};
}

export default function setup(syscall, state, helpers) {
function log(what) {
helpers.log(what);
console.log(what);
}
return helpers.makeLiveSlots(
syscall,
state,
E => harden(build(E, log)),
helpers.vatID,
);
}
43 changes: 43 additions & 0 deletions packages/swingset-runner/demo/promiseChainBenchmark/vat-bob.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import harden from '@agoric/harden';

function makePR() {
let r;
const p = new Promise((resolve, _reject) => {
r = resolve;
});
return [p, r];
}

function build(_E, _log) {
let r = null;
let value = 0;
return {
init() {
let p;
// eslint-disable-next-line prefer-const
[p, r] = makePR();
return p;
},
gen() {
// eslint-disable-next-line prefer-const
let [p, newR] = makePR();
const answer = [value, p];
value += 1;
r(answer);
r = newR;
},
};
}

export default function setup(syscall, state, helpers) {
function log(what) {
helpers.log(what);
console.log(what);
}
return helpers.makeLiveSlots(
syscall,
state,
E => harden(build(E, log)),
helpers.vatID,
);
}
52 changes: 49 additions & 3 deletions packages/swingset-runner/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {

import { dumpStore } from './dumpstore';
import { auditRefCounts } from './auditstore';
import { printStats } from './printStats';
import { printStats, printBenchmarkStats } from './printStats';

const log = console.log;

Expand Down Expand Up @@ -55,6 +55,7 @@ FLAGS may be:
--dumptag STR - prefix kernel state dump filenames with STR (default "t")
--raw - perform kernel state dumps in raw mode
--stats - print performance stats at the end of a run
--benchmark N - perform an N round benchmark after the initial run
CMD is one of:
help - print this helpful usage information
Expand Down Expand Up @@ -105,6 +106,7 @@ export async function main() {
let dumpTag = 't';
let rawMode = false;
let shouldPrintStats = false;
let benchmarkRounds = 0;

while (argv[0] && argv[0].startsWith('-')) {
const flag = argv.shift();
Expand Down Expand Up @@ -145,6 +147,9 @@ export async function main() {
case '--batchsize':
batchSize = Number(argv.shift());
break;
case '--benchmark':
benchmarkRounds = Number(argv.shift());
break;
case '--dump':
doDumps = true;
break;
Expand Down Expand Up @@ -317,6 +322,14 @@ export async function main() {
cli.displayPrompt();
},
});
cli.defineCommand('benchmark', {
help: 'Run <n> rounds of the benchmark protocol',
action: async rounds => {
const [steps, deltaT] = await runBenchmark(rounds);
log(`benchmark ${rounds} rounds, ${steps} cranks in ${deltaT} ns`);
cli.displayPrompt();
},
});
cli.defineCommand('run', {
help: 'Crank until the run queue is empty, without commit',
action: async () => {
Expand All @@ -342,11 +355,39 @@ export async function main() {
statLogger.close();
}

function getCrankNumber() {
return Number(store.storage.get('crankNumber'));
}

function kernelStateDump() {
const dumpPath = `${dumpDir}/${dumpTag}${crankNumber}`;
dumpStore(store.storage, dumpPath, rawMode);
}

async function runBenchmark(rounds) {
const cranksPre = getCrankNumber();
const statsPre = controller.getStats();
const args = { body: '[]', slots: [] };
let totalSteps = 0;
let totalDeltaT = BigInt(0);
for (let i = 0; i < rounds; i += 1) {
controller.queueToVatExport(
'_bootstrap',
'o+0',
'runBenchmarkRound',
args,
);
// eslint-disable-next-line no-await-in-loop
const [steps, deltaT] = await runBatch(0, false);
totalSteps += steps;
totalDeltaT += deltaT;
}
const cranksPost = getCrankNumber();
const statsPost = controller.getStats();
printBenchmarkStats(statsPre, statsPost, cranksPost - cranksPre, rounds);
return [totalSteps, totalDeltaT];
}

async function runBlock(requestedSteps, doCommit) {
const blockStartTime = readClock();
let actualSteps = 0;
Expand Down Expand Up @@ -428,14 +469,19 @@ export async function main() {
auditRefCounts(store.storage);
}

const [totalSteps, deltaT] = await runBatch(stepLimit, runInBlockMode);
let [totalSteps, deltaT] = await runBatch(stepLimit, runInBlockMode);
if (!runInBlockMode) {
store.commit();
}
if (shouldPrintStats) {
const cranks = Number(store.storage.get('crankNumber'));
const cranks = getCrankNumber();
printStats(controller.getStats(), cranks);
}
if (benchmarkRounds > 0) {
const [moreSteps, moreDeltaT] = await runBenchmark(benchmarkRounds);
totalSteps += moreSteps;
deltaT += moreDeltaT;
}
store.close();
if (logTimes) {
if (totalSteps) {
Expand Down
Loading

0 comments on commit 19a4ef7

Please sign in to comment.