Last Updated: 2021-03-14 15:33:16 UTC
- added macOS benchmarks (KVM virtual machine for now)
Benchmark computing Matrix Profile
This benchmark will use the current Rcpp implementation, and a real dataset of the italian power demand that contains almost 30k observations.
url <- readr::read_csv("https://raw.githubusercontent.com/matrix-profile-foundation/mpf-datasets/05efe885cff4b2266067ad62c4f6fa2b537ad2a2/real/italianpowerdemand.csv", col_names = FALSE)
dataset <- as.numeric(url$X1)
The data base
Here is a plot of the database

Let’s start the benchmark using the bench package instead of microbenchmark. First, to keep compatible with Tidyverse, and because it returns several information about memory and garbage collection usage.
The method for benchmark will be: using a matrix of data size and window size, so we can compare the performance in more than one scenario. Let’s warm up with a sample test:
sample <- head(dataset, 1000)
w_size <- 100
bench::mark(stomp = stomp(sample, w_size, progress = FALSE))
So it works.
Now let’s start the main (and intense) task.
Desktop:
- Intel(R) Core(TM) i7-7700 CPU @ 3.60Ghz.
- 32 GB RAM
- Windows 10 64-bits build 10.0.18363.1316
- WSL2 Ubuntu 20.04.1 LTS (GNU/Linux 5.4.72-microsoft-standard-WSL2 x86_64)
Raspberry:
- Quad Core 1.2GHz Cortex-A53 ARMv8 64bit CPU
- 1 GB RAM
- Raspberry Pi OS
Algorithms to be evaluated:
- STAMP (single and with 4 threads)
- STOMP (single and with 4 threads)
- SCRIMP (single and with 4 threads)
- MPX (single and with 4 threads)
The outputs will not be compared at first to avoid loosing CPU time with small variations that may occur. The code below was the one used to compute the results. They were saved and now it’s using the saved data to speedup this article rendering.
The Multithreading implementation is using the Intel TBB, some system may fallback to TinyThreads++ (at least for now, TBB was working on all tested platforms including Solaris and ARMv8). The main speed issue may be related with the mutex implementation of TinyThread++ that is not as efficient as TBB.
This is the code used to benchmark:
# changing n_workers to 4 will use 4 threads to compute
results <- bench::press(
d_size = c(5000, 10000, 15000, 20000, 25000),
w_size = c(100, 300, 500, 700, 900),
{
data <- head(dataset, d_size)
bench::mark(
stamp = stamp(data, w_size, progress = FALSE, n_workers = 1),
stomp = stomp(data, w_size, progress = FALSE, n_workers = 1),
scrimp = scrimp(data, w_size, progress = FALSE, n_workers = 1),
mpx = mpx(data, w_size, progress = FALSE, n_workers = 1),
check = FALSE,
min_iterations = 3
)
})
save(results, file = "bench.rda")
Summary of benchmarks


A curious comparison, a desktop single thread vs Raspberry Pi 3 B with four threads:

Detailed benchmarks
Single thread experiments
Four threads experiments
ARM


Cubietruck Plus ARM - Eight Threads is depicted below. I find out that R some times don’t have all cores available and is unpredictable [link].


LS0tCnRpdGxlOiAiTWF0cml4IFByb2ZpbGUgZm9yIFIgLSBCZW5jaG1hcmtzIgphdXRob3I6ICJGcmFuY2lzY28gQmlzY2hvZmYiCmNyZWF0aXZlX2NvbW1vbnM6IENDIEJZLVNBCmRhdGU6ICIxLzMxLzIwMjEiCm91dHB1dDoKICBodG1sX25vdGVib29rOiAKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogICAgdG9jX2RlcHRoOiA0Ci0tLQoKPGhlYWQ+Cgo8IS0tIEdsb2JhbCBzaXRlIHRhZyAoZ3RhZy5qcykgLSBHb29nbGUgQW5hbHl0aWNzIC0tPgoKYGBgez1odG1sfQo8c2NyaXB0IGFzeW5jIHNyYz0iaHR0cHM6Ly93d3cuZ29vZ2xldGFnbWFuYWdlci5jb20vZ3RhZy9qcz9pZD1VQS0xNjAwMzM5NzEtMiI+PC9zY3JpcHQ+CmBgYApgYGB7PWh0bWx9CjxzY3JpcHQ+CiAgd2luZG93LmRhdGFMYXllciA9IHdpbmRvdy5kYXRhTGF5ZXIgfHwgW107CiAgZnVuY3Rpb24gZ3RhZygpe2RhdGFMYXllci5wdXNoKGFyZ3VtZW50cyk7fQogIGd0YWcoJ2pzJywgbmV3IERhdGUoKSk7CgogIGd0YWcoJ2NvbmZpZycsICdVQS0xNjAwMzM5NzEtMicpOwo8L3NjcmlwdD4KYGBgCjwvaGVhZD4KCkxhc3QgVXBkYXRlZDogYHIgbHVicmlkYXRlOjpub3coIlVUQyIpYCBVVEMKCi0gICBhZGRlZCBtYWNPUyBiZW5jaG1hcmtzIChLVk0gdmlydHVhbCBtYWNoaW5lIGZvciBub3cpCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoYmVuY2gpCmxpYnJhcnkoZm9yY2F0cykKbGlicmFyeShkcGx5cikKbGlicmFyeShtYXRyaXhwcm9maWxlcikKYGBgCgojIyBCZW5jaG1hcmsgY29tcHV0aW5nIE1hdHJpeCBQcm9maWxlCgpUaGlzIGJlbmNobWFyayB3aWxsIHVzZSB0aGUgY3VycmVudCBSY3BwIGltcGxlbWVudGF0aW9uLCBhbmQgYSByZWFsIGRhdGFzZXQgb2YgdGhlIGl0YWxpYW4gcG93ZXIgZGVtYW5kIHRoYXQgY29udGFpbnMgYWxtb3N0IDMwayBvYnNlcnZhdGlvbnMuCgpgYGB7ciBpbXBvcnQgZGF0YWJhc2UsIG1lc3NhZ2U9RkFMU0V9CnVybCA8LSByZWFkcjo6cmVhZF9jc3YoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9tYXRyaXgtcHJvZmlsZS1mb3VuZGF0aW9uL21wZi1kYXRhc2V0cy8wNWVmZTg4NWNmZjRiMjI2NjA2N2FkNjJjNGY2ZmEyYjUzN2FkMmEyL3JlYWwvaXRhbGlhbnBvd2VyZGVtYW5kLmNzdiIsIGNvbF9uYW1lcyA9IEZBTFNFKQpkYXRhc2V0IDwtIGFzLm51bWVyaWModXJsJFgxKQpgYGAKCiMjIFRoZSBkYXRhIGJhc2UKCkhlcmUgaXMgYSBwbG90IG9mIHRoZSBkYXRhYmFzZQoKYGBge3IgcHJlc3N1cmUsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9MywgZmlnLndpZHRoPTEwfQpwbG90KGRhdGFzZXQsIHhsYWIgPSAib2JzZXJ2YXRpb25zIiwgeWxhYiA9ICJjb25zdW1wdGlvbiIsIHR5cGUgPSAibCIsIG1haW4gPSAiSXRhbGlhbiBQb3dlciBEZW1hbmQiKQpgYGAKCkxldCdzIHN0YXJ0IHRoZSBiZW5jaG1hcmsgdXNpbmcgdGhlIGBiZW5jaGAgcGFja2FnZSBpbnN0ZWFkIG9mIGBtaWNyb2JlbmNobWFya2AuCkZpcnN0LCB0byBrZWVwIGNvbXBhdGlibGUgd2l0aCBUaWR5dmVyc2UsIGFuZCBiZWNhdXNlIGl0IHJldHVybnMgc2V2ZXJhbCBpbmZvcm1hdGlvbiBhYm91dCBtZW1vcnkgYW5kIGdhcmJhZ2UgY29sbGVjdGlvbiB1c2FnZS4KClRoZSBtZXRob2QgZm9yIGJlbmNobWFyayB3aWxsIGJlOiB1c2luZyBhIG1hdHJpeCBvZiBkYXRhIHNpemUgYW5kIHdpbmRvdyBzaXplLCBzbyB3ZSBjYW4gY29tcGFyZSB0aGUgcGVyZm9ybWFuY2UgaW4gbW9yZSB0aGFuIG9uZSBzY2VuYXJpby4KTGV0J3Mgd2FybSB1cCB3aXRoIGEgc2FtcGxlIHRlc3Q6CgpgYGB7ciB3YXJtdXAsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgpzYW1wbGUgPC0gaGVhZChkYXRhc2V0LCAxMDAwKQp3X3NpemUgPC0gMTAwCgpiZW5jaDo6bWFyayhzdG9tcCA9IHN0b21wKHNhbXBsZSwgd19zaXplLCBwcm9ncmVzcyA9IEZBTFNFKSkKYGBgCgpTbyBpdCB3b3Jrcy4KCk5vdyBsZXQncyBzdGFydCB0aGUgbWFpbiAoYW5kIGludGVuc2UpIHRhc2suCgpEZXNrdG9wOgoKLSAgIEludGVsKFIpIENvcmUoVE0pIGk3LTc3MDAgQ1BVIFxAIDMuNjBHaHouCi0gICAzMiBHQiBSQU0KLSAgIFdpbmRvd3MgMTAgNjQtYml0cyBidWlsZCAxMC4wLjE4MzYzLjEzMTYKLSAgIFdTTDIgVWJ1bnR1IDIwLjA0LjEgTFRTIChHTlUvTGludXggNS40LjcyLW1pY3Jvc29mdC1zdGFuZGFyZC1XU0wyIHg4Nl82NCkKClJhc3BiZXJyeToKCi0gICBRdWFkIENvcmUgMS4yR0h6IENvcnRleC1BNTMgQVJNdjggNjRiaXQgQ1BVCi0gICAxIEdCIFJBTQotICAgUmFzcGJlcnJ5IFBpIE9TCgpBbGdvcml0aG1zIHRvIGJlIGV2YWx1YXRlZDoKCi0gICBTVEFNUCAoc2luZ2xlIGFuZCB3aXRoIDQgdGhyZWFkcykKLSAgIFNUT01QIChzaW5nbGUgYW5kIHdpdGggNCB0aHJlYWRzKQotICAgU0NSSU1QIChzaW5nbGUgYW5kIHdpdGggNCB0aHJlYWRzKQotICAgTVBYIChzaW5nbGUgYW5kIHdpdGggNCB0aHJlYWRzKQoKVGhlIG91dHB1dHMgd2lsbCBub3QgYmUgY29tcGFyZWQgYXQgZmlyc3QgdG8gYXZvaWQgbG9vc2luZyBDUFUgdGltZSB3aXRoIHNtYWxsIHZhcmlhdGlvbnMgdGhhdCBtYXkgb2NjdXIuClRoZSBjb2RlIGJlbG93IHdhcyB0aGUgb25lIHVzZWQgdG8gY29tcHV0ZSB0aGUgcmVzdWx0cy4KVGhleSB3ZXJlIHNhdmVkIGFuZCBub3cgaXQncyB1c2luZyB0aGUgc2F2ZWQgZGF0YSB0byBzcGVlZHVwIHRoaXMgYXJ0aWNsZSByZW5kZXJpbmcuCgpUaGUgTXVsdGl0aHJlYWRpbmcgaW1wbGVtZW50YXRpb24gaXMgdXNpbmcgdGhlIFtJbnRlbCBUQkIsXShodHRwczovL3d3dy50aHJlYWRpbmdidWlsZGluZ2Jsb2Nrcy5vcmcvICJJbnRlbCBUQkIiKSBzb21lIHN5c3RlbSBtYXkgZmFsbGJhY2sgdG8gW1RpbnlUaHJlYWRzKytdKGh0dHA6Ly90aW55dGhyZWFkcHAuYml0c25iaXRlcy5ldS8gIlRpbnlUaHJlYWRzKysiKSAoYXQgbGVhc3QgZm9yIG5vdywgVEJCIHdhcyB3b3JraW5nIG9uIGFsbCB0ZXN0ZWQgcGxhdGZvcm1zIGluY2x1ZGluZyBTb2xhcmlzIGFuZCBBUk12OCkuClRoZSBtYWluIHNwZWVkIGlzc3VlIG1heSBiZSByZWxhdGVkIHdpdGggdGhlIG11dGV4IGltcGxlbWVudGF0aW9uIG9mIFRpbnlUaHJlYWQrKyB0aGF0IGlzIG5vdCBhcyBlZmZpY2llbnQgYXMgVEJCLgoKVGhpcyBpcyB0aGUgY29kZSB1c2VkIHRvIGJlbmNobWFyazoKCmBgYHtyIGZ1bGwgYmVuY2htYXJrIHNpbmdsZSB0aHJlYWQsIGV2YWw9RkFMU0V9CiMgY2hhbmdpbmcgbl93b3JrZXJzIHRvIDQgd2lsbCB1c2UgNCB0aHJlYWRzIHRvIGNvbXB1dGUKcmVzdWx0cyA8LSBiZW5jaDo6cHJlc3MoCiAgZF9zaXplID0gYyg1MDAwLCAxMDAwMCwgMTUwMDAsIDIwMDAwLCAyNTAwMCksCiAgd19zaXplID0gYygxMDAsIDMwMCwgNTAwLCA3MDAsIDkwMCksCiAgIHsKICAgICBkYXRhIDwtIGhlYWQoZGF0YXNldCwgZF9zaXplKQoKICAgICBiZW5jaDo6bWFyaygKICAgICAgIHN0YW1wID0gc3RhbXAoZGF0YSwgd19zaXplLCBwcm9ncmVzcyA9IEZBTFNFLCBuX3dvcmtlcnMgPSAxKSwKICAgICAgIHN0b21wID0gc3RvbXAoZGF0YSwgd19zaXplLCBwcm9ncmVzcyA9IEZBTFNFLCBuX3dvcmtlcnMgPSAxKSwKICAgICAgIHNjcmltcCA9IHNjcmltcChkYXRhLCB3X3NpemUsIHByb2dyZXNzID0gRkFMU0UsIG5fd29ya2VycyA9IDEpLAogICAgICAgbXB4ID0gbXB4KGRhdGEsIHdfc2l6ZSwgcHJvZ3Jlc3MgPSBGQUxTRSwgbl93b3JrZXJzID0gMSksCiAgICAgICBjaGVjayA9IEZBTFNFLAogICAgICAgbWluX2l0ZXJhdGlvbnMgPSAzCiAgICAgKQogICB9KQpzYXZlKHJlc3VsdHMsIGZpbGUgPSAiYmVuY2gucmRhIikKCmBgYAoKIyMgU3VtbWFyeSBvZiBiZW5jaG1hcmtzCgpgYGB7ciBzdW1tYXJ5X3NpbmdsZSwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTIsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxvYWQoInJlc3VsdHMucmRhIikKcmVzX3BhciA8LSBkcGx5cjo6ZmlsdGVyKHJlc3VsdHMsIGdyZXBsKCJfcGFyIiwgYWxnb3JpdGhtKSkKcmVzX3BhciA8LSByZXNfcGFyICU+JSBtdXRhdGUoYWxnb3JpdGhtID0gc3RyaW5ncjo6c3RyX2V4dHJhY3QoYWxnb3JpdGhtLCAiLiooPz1fcGFyKSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRpYW4gPSBiZW5jaDo6YXNfYmVuY2hfdGltZShtZWRpYW4pKQoKcmVzX3NpbSA8LSBkcGx5cjo6ZmlsdGVyKHJlc3VsdHMsICFncmVwbCgiX3BhciIsIGFsZ29yaXRobSkpCnJlc19zaW0gPC0gcmVzX3NpbSAlPiUgbXV0YXRlKG1lZGlhbiA9IGJlbmNoOjphc19iZW5jaF90aW1lKG1lZGlhbikpCgpwIDwtIGdncGxvdChyZXNfc2ltLCBhZXMoeCA9IHBsYXRmb3JtLCB5ID0gbWVkaWFuLCBjb2wgPSBhbGdvcml0aG0pKQpwMiA8LSBwICsgZ2dwbG90Mjo6Z2VvbV9wb2ludChwb3NpdGlvbiA9IGdncGxvdDI6OnBvc2l0aW9uX2RvZGdlKHdpZHRoID0gLTAuMikpICsKICBnZ3Bsb3QyOjpjb29yZF9mbGlwKCkgKwogICAgbGFicyh0aXRsZSA9ICJNYXRyaXggUHJvZmlsZSBhbGdvcml0aG1zIGJlbmNobWFyayBieSBwbGF0Zm9ybSIsIHN1YnRpdGxlID0gIlNpbmdsZSBUaHJlYWRzIiwgeCA9ICJQbGF0Zm9ybXMiLCBjb2wgPSAiQWxnb3JpdGhtIiwgeSA9ICJ0aW1lIChsZXNzIGlzIGJldHRlcikiKSArCiAgZ2dwbG90Mjo6ZmFjZXRfZ3JpZChkX3NpemUgfiB3X3NpemUsIGxhYmVsbGVyID0gZ2dwbG90Mjo6bGFiZWxfYm90aCkKcDIKYGBgCgpgYGB7ciBzdW1tYXJ5X211bHRpLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbG9hZCgicmVzdWx0cy5yZGEiKQpyZXNfcGFyIDwtIGRwbHlyOjpmaWx0ZXIocmVzdWx0cywgZ3JlcGwoIl9wYXIiLCBhbGdvcml0aG0pKQpyZXNfcGFyIDwtIHJlc19wYXIgJT4lIG11dGF0ZShhbGdvcml0aG0gPSBzdHJpbmdyOjpzdHJfZXh0cmFjdChhbGdvcml0aG0sICIuKig/PV9wYXIpIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhbiA9IGJlbmNoOjphc19iZW5jaF90aW1lKG1lZGlhbikpCgpyZXNfc2ltIDwtIGRwbHlyOjpmaWx0ZXIocmVzdWx0cywgIWdyZXBsKCJfcGFyIiwgYWxnb3JpdGhtKSkKcmVzX3NpbSA8LSByZXNfc2ltICU+JSBtdXRhdGUobWVkaWFuID0gYmVuY2g6OmFzX2JlbmNoX3RpbWUobWVkaWFuKSkKCnAgPC0gZ2dwbG90KHJlc19wYXIsIGFlcyh4ID0gcGxhdGZvcm0sIHkgPSBtZWRpYW4sIGNvbCA9IGFsZ29yaXRobSkpCnAyIDwtIHAgKyBnZ3Bsb3QyOjpnZW9tX3BvaW50KHBvc2l0aW9uID0gZ2dwbG90Mjo6cG9zaXRpb25fZG9kZ2Uod2lkdGggPSAtMC4yKSkgKwogIGdncGxvdDI6OmNvb3JkX2ZsaXAoKSArCiAgICBsYWJzKHRpdGxlID0gIk1hdHJpeCBQcm9maWxlIGFsZ29yaXRobXMgYmVuY2htYXJrIGJ5IHBsYXRmb3JtIiwgc3VidGl0bGUgPSAiRm91ciBUaHJlYWRzIiwgeCA9ICJQbGF0Zm9ybXMiLCBjb2wgPSAiQWxnb3JpdGhtIiwgeSA9ICJ0aW1lIChsZXNzIGlzIGJldHRlcikiKSArCiAgZ2dwbG90Mjo6ZmFjZXRfZ3JpZChkX3NpemUgfiB3X3NpemUsIGxhYmVsbGVyID0gZ2dwbG90Mjo6bGFiZWxfYm90aCkKcDIKYGBgCgpBIGN1cmlvdXMgY29tcGFyaXNvbiwgYSBkZXNrdG9wIHNpbmdsZSB0aHJlYWQgdnMgUmFzcGJlcnJ5IFBpIDMgQiB3aXRoIGZvdXIgdGhyZWFkczoKCmBgYHtyIHN1bW1hcnlfY29tcCwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9MTIsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxvYWQoInJlc3VsdHNfYmVuY2hzLnJkYSIpCndpbl9yYXNwIDwtIGRwbHlyOjpmaWx0ZXIocmVzdWx0cywgKHBsYXRmb3JtID09ICJ3aW5kb3dzIiAmICFncmVwbCgiX3BhciIsIGFsZ29yaXRobSkpIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChwbGF0Zm9ybSA9PSAicmFzcDNiIiAmIGdyZXBsKCJfcGFyIiwgYWxnb3JpdGhtKSkpICU+JQogICBtdXRhdGUoYWxnb3JpdGhtID0gY2FzZV93aGVuKAogICAgIHBsYXRmb3JtID09ICJyYXNwM2IiIH4gc3RyaW5ncjo6c3RyX2V4dHJhY3QoYWxnb3JpdGhtLCAiLiooPz1fcGFyKSIpLAogICAgIFRSVUUgfiBhbGdvcml0aG0KICAgKSwgbWVkaWFuID0gYmVuY2g6OmFzX2JlbmNoX3RpbWUobWVkaWFuKSkgJT4lCiAgZHBseXI6OmZpbHRlcihhbGdvcml0aG0gIT0gInN0YW1wIikKCnAgPC0gZ2dwbG90KHdpbl9yYXNwLCBhZXMoeCA9IHBsYXRmb3JtLCB5ID0gbWVkaWFuLCBjb2wgPSBhbGdvcml0aG0pKQpwMiA8LSBwICsgZ2dwbG90Mjo6Z2VvbV9wb2ludChwb3NpdGlvbiA9IGdncGxvdDI6OnBvc2l0aW9uX2RvZGdlKHdpZHRoID0gLTAuMikpICsKICBnZ3Bsb3QyOjpjb29yZF9mbGlwKCkgKwogIGxhYnModGl0bGUgPSAiTWF0cml4IFByb2ZpbGUgYWxnb3JpdGhtcyBiZW5jaG1hcmsgYnkgcGxhdGZvcm0iLCBzdWJ0aXRsZSA9ICJBIGNvbXBhcmF0aXZlIG9mIFdpbmRvd3Mgd2l0aCBTaW5nbGUgVGhyZWFkIGFuZCBSYXNwYmVycnkgUGkgMyBCIHdpdGggRm91ciBUaHJlYWRzIiwgeCA9ICJQbGF0Zm9ybXMiLCBjb2wgPSAiQWxnb3JpdGhtIiwgeSA9ICJ0aW1lIChsZXNzIGlzIGJldHRlcikiKSArCiAgZ2dwbG90Mjo6ZmFjZXRfZ3JpZChkX3NpemUgfiB3X3NpemUsIGxhYmVsbGVyID0gZ2dwbG90Mjo6bGFiZWxfYm90aCkKcDIKCmBgYAoKIyMgRGV0YWlsZWQgYmVuY2htYXJrcwoKIyMjIFNpbmdsZSB0aHJlYWQgZXhwZXJpbWVudHMKCiMjIyMgeDg2CgpgYGB7ciBtZW1fYWxsb2Nfc2luZ2xlLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KbG9hZCgiYmVuY2hfd2luZG93c19zaW5nbGUucmRhIikKcmVzIDwtIGJlbmNoX3dpbmRvd3Nfc2luZ2xlCnAgPC0gZ2dwbG90Mjo6Z2dwbG90KHJlcykKcCA8LSBwICsgZ2dwbG90Mjo6YWVzX3N0cmluZygiZXhwcmVzc2lvbiIsICJ0aW1lIiwgc2l6ZSA9ICJtZW1fYWxsb2MiKSArIGdncGxvdDI6Omdlb21faml0dGVyKCkgKwogIGdncGxvdDI6OmNvb3JkX2ZsaXAoKQpwICsgbGFicyh0aXRsZSA9ICJXaW5kb3dzIDEwIC0gU2luZ2xlIFRocmVhZCAtIFNwZWVkIGFuZCBUb3RhbCBNZW1vcnkgYWxsb2NhdGlvbiAoTUIpIiwgc3VidGl0bGUgPSAiSW50ZWwoUikgQ29yZShUTSkgaTctNzcwMCBDUFUgQCAzLjYwR2h6Iix4ID0gIkFsZ29yaXRobSIsIHkgPSAidGltZSAobGVzcyBpcyBiZXR0ZXIpIiwgc2l6ZSA9ICJtYWxsb2MoTUIpIikgKwogIGdncGxvdDI6OmZhY2V0X2dyaWQoZF9zaXplIH4gd19zaXplLCBsYWJlbGxlciA9IGdncGxvdDI6OmxhYmVsX2JvdGgpCmBgYAoKYGBge3IgbWVtX2FsbG9jX3NpbmdsZV9saW51eCwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTJ9CmxvYWQoImJlbmNoX2xpbnV4X3NpbmdsZS5yZGEiKQpyZXMgPC0gYmVuY2hfbGludXhfc2luZ2xlCnAgPC0gZ2dwbG90Mjo6Z2dwbG90KHJlcykKcCA8LSBwICsgZ2dwbG90Mjo6YWVzX3N0cmluZygiZXhwcmVzc2lvbiIsICJ0aW1lIiwgc2l6ZSA9ICJtZW1fYWxsb2MiKSArIGdncGxvdDI6Omdlb21faml0dGVyKCkgKwogIGdncGxvdDI6OmNvb3JkX2ZsaXAoKQpwICsgbGFicyh0aXRsZSA9ICJVYnVudHUgV1NMIC0gU2luZ2xlIFRocmVhZCAtIFNwZWVkIGFuZCBUb3RhbCBNZW1vcnkgYWxsb2NhdGlvbiAoTUIpIiwgc3VidGl0bGUgPSAiSW50ZWwoUikgQ29yZShUTSkgaTctNzcwMCBDUFUgQCAzLjYwR2h6Iix4ID0gIkFsZ29yaXRobSIsIHkgPSAidGltZSAobGVzcyBpcyBiZXR0ZXIpIiwgc2l6ZSA9ICJtYWxsb2MoTUIpIikgKwogIGdncGxvdDI6OmZhY2V0X2dyaWQoZF9zaXplIH4gd19zaXplLCBsYWJlbGxlciA9IGdncGxvdDI6OmxhYmVsX2JvdGgpCmBgYAoKYGBge3IgbWVtX2FsbG9jX3NpbmdsZV9vc3gsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQpsb2FkKCJiZW5jaF9tYWNvc3hfc2luZ2xlLnJkYSIpCnJlcyA8LSBiZW5jaF9tYWNvc3hfc2luZ2xlCnAgPC0gZ2dwbG90Mjo6Z2dwbG90KHJlcykKcCA8LSBwICsgZ2dwbG90Mjo6YWVzX3N0cmluZygiZXhwcmVzc2lvbiIsICJ0aW1lIiwgc2l6ZSA9ICJtZW1fYWxsb2MiKSArIGdncGxvdDI6Omdlb21faml0dGVyKCkgKwogIGdncGxvdDI6OmNvb3JkX2ZsaXAoKQpwICsgbGFicyh0aXRsZSA9ICJtYWNPUyBIaWdoIFNpZXJyYSBLVk0gLSBTaW5nbGUgVGhyZWFkcyAtIFNwZWVkIGFuZCBUb3RhbCBNZW1vcnkgYWxsb2NhdGlvbiAoTUIpIiwgc3VidGl0bGUgPSAiSW50ZWwoUikgQ29yZShUTSkgaTUtNDMwTSBDUFUgQCAyLjI2LTIuNTNHaHoiLHggPSAiQWxnb3JpdGhtIiwgeSA9ICJ0aW1lIChsZXNzIGlzIGJldHRlcikiLCBzaXplID0gIm1hbGxvYyhNQikiKSArCiAgZ2dwbG90Mjo6ZmFjZXRfZ3JpZChkX3NpemUgfiB3X3NpemUsIGxhYmVsbGVyID0gZ2dwbG90Mjo6bGFiZWxfYm90aCkKYGBgCgojIyMjIEFSTQoKYGBge3IgbWVtX2FsbG9jX3NpbmdsZV9hcm0sIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQpsb2FkKCJiZW5jaF9hcm1fc2luZ2xlLnJkYSIpCnJlcyA8LSBiZW5jaF9hcm1fc2luZ2xlCnAgPC0gZ2dwbG90Mjo6Z2dwbG90KHJlcykKcCA8LSBwICsgZ2dwbG90Mjo6YWVzX3N0cmluZygiZXhwcmVzc2lvbiIsICJ0aW1lIikgKyBnZ3Bsb3QyOjpnZW9tX2ppdHRlcigpICsKICBnZ3Bsb3QyOjpjb29yZF9mbGlwKCkKcCArIGxhYnModGl0bGUgPSAiUmFzcGJlcnJ5IFBpIE9TIEFSTSAtIFNpbmdsZSBUaHJlYWQgLSBTcGVlZCAobWFsbG9jIG5vdCBhdmFpbGFibGUgaW4gQVJNKSIsIHN1YnRpdGxlID0gIlJhc3BiZXJyeSBQaSAzIE1vZGVsIEIsIFF1YWQgQ29yZSAxLjJHSHogQ29ydGV4LUE1MyBBUk12OCIseCA9ICJBbGdvcml0aG0iLCB5ID0gInRpbWUgKGxlc3MgaXMgYmV0dGVyKSIpICsKZ2dwbG90Mjo6ZmFjZXRfZ3JpZChkX3NpemUgfiB3X3NpemUsIGxhYmVsbGVyID0gZ2dwbG90Mjo6bGFiZWxfYm90aCkKYGBgCgpgYGB7ciBtZW1fYWxsb2Nfc2luZ2xlX2FybXRydWNrLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KbG9hZCgiYmVuY2hfY3ViaWVfc2luZ2xlLnJkYSIpCnJlcyA8LSBiZW5jaF9jdWJpZV9zaW5nbGUKcCA8LSBnZ3Bsb3QyOjpnZ3Bsb3QocmVzKQpwIDwtIHAgKyBnZ3Bsb3QyOjphZXNfc3RyaW5nKCJleHByZXNzaW9uIiwgInRpbWUiKSArIGdncGxvdDI6Omdlb21faml0dGVyKCkgKwogIGdncGxvdDI6OmNvb3JkX2ZsaXAoKQpwICsgbGFicyh0aXRsZSA9ICJDdWJpZXRydWNrIFBsdXMgQVJNIC0gU2luZ2xlIFRocmVhZCAtIFNwZWVkIChtYWxsb2Mgbm90IGF2YWlsYWJsZSBpbiBBUk0pIiwgc3VidGl0bGUgPSAiQ3ViaWV0cnVjayBQbHVzLCBPY3RhIENvcmUgMkdIeiBDb3J0ZXgtQTcgQVJNdjciLHggPSAiQWxnb3JpdGhtIiwgeSA9ICJ0aW1lIChsZXNzIGlzIGJldHRlcikiKSArCmdncGxvdDI6OmZhY2V0X2dyaWQoZF9zaXplIH4gd19zaXplLCBsYWJlbGxlciA9IGdncGxvdDI6OmxhYmVsX2JvdGgpCmBgYAoKYGBge3IgY3ViaWVfdnNfcmFzcGlfc2luZ2xlLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KYmVuY2hfYXJtX3NpbmdsZSRjcHUgPC0gInJhc3AzYiIKYmVuY2hfY3ViaWVfc2luZ2xlJGNwdSA8LSAiY3RwbHVzIgpyZXMgPC0gcmJpbmQoYmVuY2hfYXJtX3NpbmdsZSwgYmVuY2hfY3ViaWVfc2luZ2xlKQpwIDwtIGdncGxvdDI6OmdncGxvdChyZXMpCnAgPC0gcCArIGdncGxvdDI6OmFlc19zdHJpbmcoImV4cHJlc3Npb24iLCAidGltZSIsIGNvbCA9ICJjcHUiKSArIGdncGxvdDI6Omdlb21faml0dGVyKCkgKwogIGdncGxvdDI6OmNvb3JkX2ZsaXAoKQpwICsgbGFicyh0aXRsZSA9ICJDdWJpZXRydWNrIFBsdXMgdnMgUmFzcGJlcnJ5IFBpIDMgQiAtIFNwZWVkIChtYWxsb2Mgbm90IGF2YWlsYWJsZSBpbiBBUk0pIiwgc3VidGl0bGUgPSAiU2luZ2xlIFRocmVhZCIseCA9ICJBbGdvcml0aG0iLCB5ID0gInRpbWUgKGxlc3MgaXMgYmV0dGVyKSIsIGNvbCA9ICJQbGF0Zm9ybSIpICsgZ2dwbG90Mjo6ZmFjZXRfZ3JpZChkX3NpemUgfiB3X3NpemUsIGxhYmVsbGVyID0gZ2dwbG90Mjo6bGFiZWxfYm90aCkKYGBgCgojIyMgRm91ciB0aHJlYWRzIGV4cGVyaW1lbnRzCgojIyMjIHg4NgoKYGBge3IgbWVtX3RocmVhZF93aW5kb3dzLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KbG9hZCgiYmVuY2hfd2luZG93c190aHJlYWQucmRhIikKcmVzIDwtIGJlbmNoX3dpbmRvd3NfdGhyZWFkCnAgPC0gZ2dwbG90Mjo6Z2dwbG90KHJlcykKcCA8LSBwICsgZ2dwbG90Mjo6YWVzX3N0cmluZygiZXhwcmVzc2lvbiIsICJ0aW1lIiwgc2l6ZSA9ICJtZW1fYWxsb2MiKSArIGdncGxvdDI6Omdlb21faml0dGVyKCkgKwogIGdncGxvdDI6OmNvb3JkX2ZsaXAoKQpwICsgbGFicyh0aXRsZSA9ICJXaW5kb3dzIDEwIC0gRm91ciBUaHJlYWRzIC0gU3BlZWQgYW5kIFRvdGFsIE1lbW9yeSBhbGxvY2F0aW9uIChNQikiLCBzdWJ0aXRsZSA9ICJJbnRlbChSKSBDb3JlKFRNKSBpNy03NzAwIENQVSBAIDMuNjBHaHoiLHggPSAiQWxnb3JpdGhtIiwgeSA9ICJ0aW1lIChsZXNzIGlzIGJldHRlcikiLCBzaXplID0gIm1hbGxvYyhNQikiKSArCiAgZ2dwbG90Mjo6ZmFjZXRfZ3JpZChkX3NpemUgfiB3X3NpemUsIGxhYmVsbGVyID0gZ2dwbG90Mjo6bGFiZWxfYm90aCkKYGBgCgpgYGB7ciBtZW1fdGhyZWFkX2xpbnV4LCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KbG9hZCgiYmVuY2hfbGludXhfdGhyZWFkLnJkYSIpCnJlcyA8LSBiZW5jaF9saW51eF90aHJlYWQKcCA8LSBnZ3Bsb3QyOjpnZ3Bsb3QocmVzKQpwIDwtIHAgKyBnZ3Bsb3QyOjphZXNfc3RyaW5nKCJleHByZXNzaW9uIiwgInRpbWUiLCBzaXplID0gIm1lbV9hbGxvYyIpICsgZ2dwbG90Mjo6Z2VvbV9qaXR0ZXIoKSArCiAgZ2dwbG90Mjo6Y29vcmRfZmxpcCgpCnAgKyBsYWJzKHRpdGxlID0gIlVidW50dSBXU0wgLSBGb3VyIFRocmVhZHMgLSBTcGVlZCBhbmQgVG90YWwgTWVtb3J5IGFsbG9jYXRpb24gKE1CKSIsIHN1YnRpdGxlID0gIkludGVsKFIpIENvcmUoVE0pIGk3LTc3MDAgQ1BVIEAgMy42MEdoeiIseCA9ICJBbGdvcml0aG0iLCB5ID0gInRpbWUgKGxlc3MgaXMgYmV0dGVyKSIsIHNpemUgPSAibWFsbG9jKE1CKSIpICsKICBnZ3Bsb3QyOjpmYWNldF9ncmlkKGRfc2l6ZSB+IHdfc2l6ZSwgbGFiZWxsZXIgPSBnZ3Bsb3QyOjpsYWJlbF9ib3RoKQpgYGAKCmBgYHtyIG1hY29zeF9tdWx0aSwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTJ9CmxvYWQoImJlbmNoX21hY29zeF90aHJlYWQucmRhIikKcmVzIDwtIGJlbmNoX21hY29zeF90aHJlYWQKcCA8LSBnZ3Bsb3QyOjpnZ3Bsb3QocmVzKQpwIDwtIHAgKyBnZ3Bsb3QyOjphZXNfc3RyaW5nKCJleHByZXNzaW9uIiwgInRpbWUiLCBzaXplID0gIm1lbV9hbGxvYyIpICsgZ2dwbG90Mjo6Z2VvbV9qaXR0ZXIoKSArCiAgZ2dwbG90Mjo6Y29vcmRfZmxpcCgpCnAgKyBsYWJzKHRpdGxlID0gIm1hY09TIEhpZ2ggU2llcnJhIEtWTSAtIEZvdXIgVGhyZWFkcyAtIFNwZWVkIGFuZCBUb3RhbCBNZW1vcnkgYWxsb2NhdGlvbiAoTUIpIiwgc3VidGl0bGUgPSAiSW50ZWwoUikgQ29yZShUTSkgaTUtNDMwTSBDUFUgQCAyLjI2LTIuNTNHaHoiLHggPSAiQWxnb3JpdGhtIiwgeSA9ICJ0aW1lIChsZXNzIGlzIGJldHRlcikiLCBzaXplID0gIm1hbGxvYyhNQikiKSArCiAgZ2dwbG90Mjo6ZmFjZXRfZ3JpZChkX3NpemUgfiB3X3NpemUsIGxhYmVsbGVyID0gZ2dwbG90Mjo6bGFiZWxfYm90aCkKYGBgCgojIyMjIEFSTQoKYGBge3IgbWVtX2FsbG9jX3RocmVhZF9hcm0sIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQpsb2FkKCJiZW5jaF9hcm1fdGhyZWFkLnJkYSIpCnJlcyA8LSBiZW5jaF9hcm1fdGhyZWFkCnAgPC0gZ2dwbG90Mjo6Z2dwbG90KHJlcykKcCA8LSBwICsgZ2dwbG90Mjo6YWVzX3N0cmluZygiZXhwcmVzc2lvbiIsICJ0aW1lIikgKyBnZ3Bsb3QyOjpnZW9tX2ppdHRlcigpICsKICBnZ3Bsb3QyOjpjb29yZF9mbGlwKCkKcCArIGxhYnModGl0bGUgPSAiUmFzcGJlcnJ5IFBpIE9TIEFSTSAtIEZvdXIgVGhyZWFkcyAtIFNwZWVkIChtYWxsb2Mgbm90IGF2YWlsYWJsZSBpbiBBUk0pIiwgc3VidGl0bGUgPSAiUmFzcGJlcnJ5IFBpIDMgTW9kZWwgQiwgUXVhZCBDb3JlIDEuMkdIeiBDb3J0ZXgtQTUzIEFSTXY4Iix4ID0gIkFsZ29yaXRobSIsIHkgPSAidGltZSAobGVzcyBpcyBiZXR0ZXIpIikgKyBnZ3Bsb3QyOjpmYWNldF9ncmlkKGRfc2l6ZSB+IHdfc2l6ZSwgbGFiZWxsZXIgPSBnZ3Bsb3QyOjpsYWJlbF9ib3RoKQpgYGAKCmBgYHtyIG1lbV9hbGxvY190aHJlYWRfYXJtdHJ1Y2ssIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQpsb2FkKCJiZW5jaF9jdWJpZV90aHJlYWQucmRhIikKcmVzIDwtIGJlbmNoX2N1YmllX3RocmVhZApwIDwtIGdncGxvdDI6OmdncGxvdChyZXMpCnAgPC0gcCArIGdncGxvdDI6OmFlc19zdHJpbmcoImV4cHJlc3Npb24iLCAidGltZSIpICsgZ2dwbG90Mjo6Z2VvbV9qaXR0ZXIoKSArCiAgZ2dwbG90Mjo6Y29vcmRfZmxpcCgpCnAgKyBsYWJzKHRpdGxlID0gIkN1YmlldHJ1Y2sgUGx1cyBBUk0gLSBGb3VyIFRocmVhZHMgLSBTcGVlZCAobWFsbG9jIG5vdCBhdmFpbGFibGUgaW4gQVJNKSIsIHN1YnRpdGxlID0gIkN1YmlldHJ1Y2sgUGx1cywgT2N0YSBDb3JlIDJHSHogQ29ydGV4LUE3IEFSTXY3Iix4ID0gIkFsZ29yaXRobSIsIHkgPSAidGltZSAobGVzcyBpcyBiZXR0ZXIpIikgKyBnZ3Bsb3QyOjpmYWNldF9ncmlkKGRfc2l6ZSB+IHdfc2l6ZSwgbGFiZWxsZXIgPSBnZ3Bsb3QyOjpsYWJlbF9ib3RoKQpgYGAKCj4gQ3ViaWV0cnVjayBQbHVzIEFSTSAtIEVpZ2h0IFRocmVhZHMgaXMgZGVwaWN0ZWQgYmVsb3cuCj4gSSBmaW5kIG91dCB0aGF0IFIgc29tZSB0aW1lcyBkb24ndCBoYXZlIGFsbCBjb3JlcyBhdmFpbGFibGUgYW5kIGlzIHVucHJlZGljdGFibGUgW1tsaW5rXShodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNDAyMjczODAvMjE5NTMzNyldLgoKYGBge3IgbWVtX2FsbG9jX3RocmVhZF9hcm10cnVjazIsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQpsb2FkKCJiZW5jaF9jdWJpZV90aHJlYWRfZWlnaHQucmRhIikKcmVzIDwtIGJlbmNoX2N1YmllX3RocmVhZF9laWdodApwIDwtIGdncGxvdDI6OmdncGxvdChyZXMpCnAgPC0gcCArIGdncGxvdDI6OmFlc19zdHJpbmcoImV4cHJlc3Npb24iLCAidGltZSIpICsgZ2dwbG90Mjo6Z2VvbV9qaXR0ZXIoKSArCiAgZ2dwbG90Mjo6Y29vcmRfZmxpcCgpCnAgKyBsYWJzKHRpdGxlID0gIkN1YmlldHJ1Y2sgUGx1cyBBUk0gLSBFaWdodCBUaHJlYWRzIC0gU3BlZWQgKG1hbGxvYyBub3QgYXZhaWxhYmxlIGluIEFSTSkiLCBzdWJ0aXRsZSA9ICJDdWJpZXRydWNrIFBsdXMsIE9jdGEgQ29yZSAyR0h6IENvcnRleC1BNyBBUk12NyIseCA9ICJBbGdvcml0aG0iLCB5ID0gInRpbWUgKGxlc3MgaXMgYmV0dGVyKSIpICsgZ2dwbG90Mjo6ZmFjZXRfZ3JpZChkX3NpemUgfiB3X3NpemUsIGxhYmVsbGVyID0gZ2dwbG90Mjo6bGFiZWxfYm90aCkKYGBgCgpgYGB7ciBjdWJpZV92c19yYXNwaV90aHJlYWQsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQpiZW5jaF9hcm1fdGhyZWFkJGNwdSA8LSAicmFzcDNiIC0gNCIKYmVuY2hfY3ViaWVfdGhyZWFkJGNwdSA8LSAiY3RwbHVzIC0gNCIKYmVuY2hfY3ViaWVfdGhyZWFkX2VpZ2h0JGNwdSA8LSAiY3RwbHVzIC0gOCIKcmVzIDwtIHJiaW5kKGJlbmNoX2FybV90aHJlYWQsIGJlbmNoX2N1YmllX3RocmVhZF9laWdodCwgYmVuY2hfY3ViaWVfdGhyZWFkKQpwIDwtIGdncGxvdDI6OmdncGxvdChyZXMsIGFlcyh4ID0gY3B1LCB5ID0gbWVkaWFuLCBjb2wgPSBleHByZXNzaW9uKSkgKyBnZ3Bsb3QyOjpnZW9tX3BvaW50KCkgKwogIGdncGxvdDI6OmNvb3JkX2ZsaXAoKQpwICsgbGFicyh0aXRsZSA9ICJDdWJpZXRydWNrIFBsdXMgdnMgUmFzcGJlcnJ5IFBpIDMgQiAtIFNwZWVkIChtYWxsb2Mgbm90IGF2YWlsYWJsZSBpbiBBUk0pIiwgc3VidGl0bGUgPSAiRm91ci9FaWdodCBUaHJlYWRzIix4ID0gIlBsYXRmb3JtIiwgeSA9ICJ0aW1lIChsZXNzIGlzIGJldHRlcikiLCBjb2wgPSAiQWxnb3JpdGhtIikgKyBnZ3Bsb3QyOjpmYWNldF9ncmlkKGRfc2l6ZSB+IHdfc2l6ZSwgbGFiZWxsZXIgPSBnZ3Bsb3QyOjpsYWJlbF9ib3RoKQpgYGAK