diff --git a/perf/impl/nim-libp2p/v1.10/.gitignore b/perf/impl/nim-libp2p/v1.10/.gitignore index 357758b67..d95fc2b53 100644 --- a/perf/impl/nim-libp2p/v1.10/.gitignore +++ b/perf/impl/nim-libp2p/v1.10/.gitignore @@ -1,8 +1,6 @@ +# nim project nimble.develop nimble.paths - -nimlibp2p -nim-libp2p -nim-libp2p-* -nim-libp2p-*.zip \ No newline at end of file +# the binary output +perf \ No newline at end of file diff --git a/perf/impl/nim-libp2p/v1.10/Makefile b/perf/impl/nim-libp2p/v1.10/Makefile index d70ceb48a..2c01ef292 100644 --- a/perf/impl/nim-libp2p/v1.10/Makefile +++ b/perf/impl/nim-libp2p/v1.10/Makefile @@ -1,33 +1,18 @@ -# commit corresponds to v1.10.2 (draft) version of nim-libp2p -commitSha := 3a7745f920d11fb29305070cd9991874529dfc28 - all: perf -perf: perf.nim nim-libp2p +# `nim c` command uses flags to: +# - minimize output while compile - to reduce log output in the ci that runs perf benchmarking +# - optimize for speed - to have the best possible performance + +perf: perf.nim docker run --rm \ -v "$(shell pwd)":/usr/src/myapp -w /usr/src/myapp nimlang/nim:2.2.0 \ sh -c ' \ - rm -f nimlibp2p && \ - ln -s nim-libp2p nimlibp2p && \ - cd nim-libp2p && \ - nimble install_pinned && cd ../ && \ - nimble install -y --depsOnly && \ - nim c --threads:off --NimblePath:nim-libp2p/nimbledeps/pkgs -p:nim-libp2p -d:chronicles_log_level=WARN -d:release perf.nim && \ - chown -R $(shell id -u):$(shell id -g) .' - -nim-libp2p: nim-libp2p-${commitSha} - rm -rf nim-libp2p - ln -s nim-libp2p-${commitSha} nim-libp2p - -nim-libp2p-${commitSha}: nim-libp2p-${commitSha}.zip - unzip -o nim-libp2p-${commitSha}.zip - -nim-libp2p-${commitSha}.zip: - wget -O $@ "https://github.com/status-im/nim-libp2p/archive/${commitSha}.zip" + nimble install -y --depsOnly && \ + nim c --hints:off --verbosity:0 --warning[all]:off --threads:off --NimblePath:nim-libp2p/nimbledeps/pkgs -p:nim-libp2p -d:chronicles_enabled=off -d:release -d:danger -d:lto --opt:speed --stacktrace:off perf.nim && \ + chown -R $(shell id -u):$(shell id -g) .' clean: - rm -rf nim-libp2p - rm -rf nim-libp2p-${commitSha} - rm -rf nim-libp2p-${commitSha}.zip + rm -f perf .PHONY: all clean \ No newline at end of file diff --git a/perf/impl/nim-libp2p/v1.10/perf.nim b/perf/impl/nim-libp2p/v1.10/perf.nim index 850168970..7c2df0ddc 100644 --- a/perf/impl/nim-libp2p/v1.10/perf.nim +++ b/perf/impl/nim-libp2p/v1.10/perf.nim @@ -1,8 +1,7 @@ import os, strutils, strformat, json import chronos, bearssl/[rand, hash] -import ./nimlibp2p/libp2p -import - ./nimlibp2p/libp2p/[protocols/perf/client, protocols/perf/server, protocols/perf/core] +import libp2p +import libp2p/[protocols/perf/client, protocols/perf/server, protocols/perf/core] const fixedPeerId = "12D3KooWPnQpbXGqzgESFrkaFh1xvCrB64ADnLQQRYfMhnbSuFHF" @@ -34,46 +33,76 @@ proc initFlagsFromParams(flags: var Flags) = flags.downloadBytes = parseUInt(paramStr(i)) else: stderr.writeLine("unsupported flag: " & paramStr(i)) - + if flags.serverIpAddress == TransportAddress(): raise newException(ValueError, "server-address is not set") - proc seededRng(): ref HmacDrbgContext = var seed: cint = 0 var rng = (ref HmacDrbgContext)() hmacDrbgInit(rng[], addr sha256Vtable, cast[pointer](addr seed), sizeof(seed).uint) return rng -proc runServer(f: Flags) {.async.} = - let endlessFut = newFuture[void]() - var switch = SwitchBuilder +proc makeSwitch(f: Flags): Switch = + let addrs = + if f.runServer: + @[MultiAddress.init(f.serverIpAddress).tryGet()] + else: + @[MultiAddress.init("/ip4/127.0.0.1/tcp/0").tryGet()] + + let rng = + if f.runServer: + seededRng() # use fixed seed that will match fixedPeerId + else: + newRng() + + return SwitchBuilder .new() - .withRng(seededRng()) - .withAddresses(@[MultiAddress.init(f.serverIpAddress).tryGet()]) + .withRng(rng) + .withAddresses(addrs) .withTcpTransport() - # .withQuicTransport() - .withMplex() + .withYamux() .withNoise() .build() + +proc runServer(f: Flags) {.async.} = + var switch = makeSwitch(f) switch.mount(Perf.new()) await switch.start() - await endlessFut # Await forever, exit on interrupt + + await newFuture[void]() # await forever, exit on interrupt + +proc writeReport(p: PerfClient, done: Future[void]) {.async.} = + proc writeStats(stats: Stats) = + let result = + %*{ + "type": if stats.isFinal: "final" else: "intermediary", + "timeSeconds": stats.duration.nanoseconds.float / 1_000_000_000.0, + "uploadBytes": stats.uploadBytes, + "downloadBytes": stats.downloadBytes, + } + stdout.writeLine($result) + + var prevStats: Stats + while true: + await sleepAsync(1000.milliseconds) + var stats = p.currentStats() + if stats.isFinal: + writeStats(stats) + done.complete() + return + + # intermediary stats report should be diff from last intermediary report + let statsInitial = stats + stats.duration -= prevStats.duration + stats.uploadBytes -= prevStats.uploadBytes + stats.downloadBytes -= prevStats.downloadBytes + prevStats = statsInitial + + writeStats(stats) proc runClient(f: Flags) {.async.} = - let switchBuilder = SwitchBuilder - .new() - .withRng(newRng()) - .withAddress(MultiAddress.init("/ip4/127.0.0.1/tcp/0").tryGet()) - .withMplex() - .withNoise() - let switch = - case f.transport - of "tcp": - switchBuilder.withTcpTransport().build() - # of "quic-v1": switchBuilder.withQuicTransport().build() - else: - raise newException(ValueError, "unsupported transport: " & f.transport) + let switch = makeSwitch(f) await switch.start() let conn = await switch.dial( @@ -81,16 +110,12 @@ proc runClient(f: Flags) {.async.} = @[MultiAddress.init(f.serverIpAddress).tryGet()], PerfCodec, ) - let dur = await PerfClient.perf(conn, f.uploadBytes, f.downloadBytes) - - let resultFinal = - %*{ - "type": "final", - "timeSeconds": dur.seconds, - "uploadBytes": f.uploadBytes, - "downloadBytes": f.downloadBytes, - } - echo $resultFinal + var perfClient = PerfClient.new() + var done = newFuture[void]("report done") + discard perfClient.perf(conn, f.uploadBytes, f.downloadBytes) + asyncSpawn writeReport(perfClient, done) + + await done # block until reporting finishes proc main() {.async.} = var flags = Flags() diff --git a/perf/impl/nim-libp2p/v1.10/pref.nimble b/perf/impl/nim-libp2p/v1.10/pref.nimble index fc221852a..2da2fabe2 100644 --- a/perf/impl/nim-libp2p/v1.10/pref.nimble +++ b/perf/impl/nim-libp2p/v1.10/pref.nimble @@ -1,9 +1,11 @@ mode = ScriptMode.Verbose -packageName = "nim-libp2p pref" +packageName = "pref" version = "1.10" author = "Status Research & Development GmbH" -description = "LibP2P implementation" +description = "nim perf implementation" license = "MIT" requires "nim >= 2.2.0", "chronos >= 4.0.4", "bearssl >= 0.2.5" +# commit corresponds to v1.10.X (master branch) version of nim-libp2p +requires "libp2p#be1a2023ce41a4ccd298215f614820a8f3f0eb6e"