Initial commit
This commit is contained in:
182
.gitignore
vendored
Normal file
182
.gitignore
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/rust,jetbrains+all,macos,linux,windows
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=rust,jetbrains+all,macos,linux,windows
|
||||
|
||||
### JetBrains+all ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
### JetBrains+all Patch ###
|
||||
# Ignore everything but code style settings and run configurations
|
||||
# that are supposed to be shared within teams.
|
||||
|
||||
.idea/*
|
||||
|
||||
!.idea/codeStyles
|
||||
!.idea/runConfigurations
|
||||
|
||||
### Linux ###
|
||||
*~
|
||||
|
||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||
.fuse_hidden*
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
# Linux trash folder which might appear on any partition or disk
|
||||
.Trash-*
|
||||
|
||||
# .nfs files are created when an open file is removed but is still being accessed
|
||||
.nfs*
|
||||
|
||||
### macOS ###
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
### macOS Patch ###
|
||||
# iCloud generated files
|
||||
*.icloud
|
||||
|
||||
### Rust ###
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
debug/
|
||||
target/
|
||||
|
||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||
Cargo.lock
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||
*.pdb
|
||||
|
||||
### Windows ###
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
Thumbs.db:encryptable
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/rust,jetbrains+all,macos,linux,windows
|
||||
28
Cargo.toml
Normal file
28
Cargo.toml
Normal file
@@ -0,0 +1,28 @@
|
||||
[package]
|
||||
name = "ecs_dt_benchmark"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "ECS Digital Twin runtime benchmark — TRANSIT lab / UQAC"
|
||||
|
||||
# No default features: we do NOT want a window, renderer, audio, or anything
|
||||
# that requires a display. Pure headless ECS.
|
||||
[dependencies]
|
||||
bevy_ecs = { version = "0.18", default-features = false }
|
||||
rand = { version = "0.8", features = ["small_rng"] }
|
||||
rand_chacha = "0.3"
|
||||
|
||||
[profile.release]
|
||||
opt-level = 3
|
||||
lto = "thin" # thin LTO: good balance between link time and perf
|
||||
codegen-units = 1 # single CGU for max inlining across crate boundary
|
||||
panic = "abort" # smaller binary, no unwinding overhead
|
||||
|
||||
[profile.bench]
|
||||
inherits = "release"
|
||||
debug = true # keep symbols so perf/flamegraph works on RPi
|
||||
|
||||
# On aarch64 (RPi 5 Cortex-A76) the compiler can use NEON by default.
|
||||
# Uncomment the line below for the RPi 5 build to also enable SVE if your
|
||||
# toolchain supports it (most don't yet for aarch64-unknown-linux-gnu):
|
||||
# [target.aarch64-unknown-linux-gnu]
|
||||
# rustflags = ["-C", "target-cpu=cortex-a76"]
|
||||
35
results/csv/entities_10000.txt
Normal file
35
results/csv/entities_10000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=10000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=7000 EventAsset=2000 ActuatorAsset=1000 total=10000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 10000 (sensor_active= 8817, alerts= 0, act= 1000) | faults= 183 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 94.0 sim= 20.0 export= 11.0 diag= 0.0 µs | exported=0.08 MB acks=1000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 10000 (sensor_active= 4488, alerts= 23, act= 1000) | faults= 92482 lockouts= 0 | rss= 0.0 MB | tick_mean= 105.6 µs | ingest= 48.8 sim= 6.0 export= 3.9 diag= 0.0 µs | exported=40.70 MB acks=501000
|
||||
tick= 2000 | entities= 10000 (sensor_active= 4425, alerts= 23, act= 1000) | faults=182979 lockouts= 0 | rss= 0.0 MB | tick_mean= 105.6 µs | ingest= 48.6 sim= 5.9 export= 3.9 diag= 0.0 µs | exported=121.92 MB acks=1501000
|
||||
tick= 3000 | entities= 10000 (sensor_active= 4507, alerts= 27, act= 1000) | faults=273085 lockouts= 0 | rss= 0.0 MB | tick_mean= 105.2 µs | ingest= 48.6 sim= 5.9 export= 3.9 diag= 0.0 µs | exported=203.15 MB acks=2501000
|
||||
tick= 4000 | entities= 10000 (sensor_active= 4502, alerts= 15, act= 1000) | faults=363376 lockouts= 0 | rss= 0.0 MB | tick_mean= 105.6 µs | ingest= 48.8 sim= 5.9 export= 3.9 diag= 0.0 µs | exported=284.37 MB acks=3501000
|
||||
tick= 5000 | entities= 10000 (sensor_active= 4527, alerts= 24, act= 1000) | faults=453183 lockouts= 0 | rss= 0.0 MB | tick_mean= 105.8 µs | ingest= 48.9 sim= 5.9 export= 3.9 diag= 0.0 µs | exported=365.59 MB acks=4501000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 0.531 s
|
||||
Sustained tick rate: 9424.5 Hz
|
||||
Per-tick mean (wall): 10.6 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 48.8
|
||||
SimulationSystem: 5.9
|
||||
ExportSystem: 3.9
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 498016
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 406.11 MB
|
||||
Acks processed: 5000000
|
||||
Alerts seen: 104943
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results/csv/entities_100000.txt
Normal file
35
results/csv/entities_100000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=100000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=70000 EventAsset=20000 ActuatorAsset=10000 total=100000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 100000 (sensor_active= 88228, alerts= 0, act=10000) | faults= 1772 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 202.0 sim= 75.0 export= 41.0 diag= 0.0 µs | exported=0.81 MB acks=10000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 100000 (sensor_active= 45396, alerts= 218, act=10000) | faults=924085 lockouts= 0 | rss= 0.0 MB | tick_mean= 1101.8 µs | ingest= 500.9 sim= 61.2 export= 40.6 diag= 0.0 µs | exported=406.92 MB acks=5010000
|
||||
tick= 2000 | entities= 100000 (sensor_active= 44998, alerts= 212, act=10000) | faults=1823730 lockouts= 0 | rss= 0.0 MB | tick_mean= 1105.1 µs | ingest= 501.0 sim= 61.1 export= 40.6 diag= 0.0 µs | exported=1219.14 MB acks=15010000
|
||||
tick= 3000 | entities= 100000 (sensor_active= 45132, alerts= 187, act=10000) | faults=2723608 lockouts= 0 | rss= 0.0 MB | tick_mean= 1114.2 µs | ingest= 504.7 sim= 61.5 export= 40.8 diag= 0.0 µs | exported=2031.31 MB acks=25010000
|
||||
tick= 4000 | entities= 100000 (sensor_active= 45039, alerts= 226, act=10000) | faults=3624295 lockouts= 0 | rss= 0.0 MB | tick_mean= 1112.0 µs | ingest= 505.0 sim= 61.7 export= 40.9 diag= 0.0 µs | exported=2843.48 MB acks=35010000
|
||||
tick= 5000 | entities= 100000 (sensor_active= 45069, alerts= 206, act=10000) | faults=4525217 lockouts= 0 | rss= 0.0 MB | tick_mean= 1112.9 µs | ingest= 504.7 sim= 61.8 export= 40.9 diag= 0.0 µs | exported=3655.68 MB acks=45010000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 5.555 s
|
||||
Sustained tick rate: 900.2 Hz
|
||||
Per-tick mean (wall): 111.2 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 504.2
|
||||
SimulationSystem: 61.8
|
||||
ExportSystem: 41.0
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 4974449
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 4060.96 MB
|
||||
Acks processed: 50000000
|
||||
Alerts seen: 1028407
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results/csv/entities_150000.txt
Normal file
35
results/csv/entities_150000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=150000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=105000 EventAsset=30000 ActuatorAsset=15000 total=150000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 150000 (sensor_active=132379, alerts= 0, act=15000) | faults= 2621 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 306.0 sim= 113.0 export= 61.0 diag= 0.0 µs | exported=1.22 MB acks=15000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 150000 (sensor_active= 67721, alerts= 326, act=15000) | faults=1385323 lockouts= 0 | rss= 0.0 MB | tick_mean= 1717.3 µs | ingest= 755.7 sim= 92.9 export= 61.8 diag= 0.0 µs | exported=610.34 MB acks=7515000
|
||||
tick= 2000 | entities= 150000 (sensor_active= 67238, alerts= 278, act=15000) | faults=2736064 lockouts= 0 | rss= 0.0 MB | tick_mean= 1721.7 µs | ingest= 755.2 sim= 93.0 export= 61.8 diag= 0.0 µs | exported=1828.59 MB acks=22515000
|
||||
tick= 3000 | entities= 150000 (sensor_active= 67728, alerts= 330, act=15000) | faults=4087020 lockouts= 0 | rss= 0.0 MB | tick_mean= 1719.6 µs | ingest= 753.9 sim= 93.0 export= 61.5 diag= 0.0 µs | exported=3046.89 MB acks=37515000
|
||||
tick= 4000 | entities= 150000 (sensor_active= 67533, alerts= 323, act=15000) | faults=5437256 lockouts= 0 | rss= 0.0 MB | tick_mean= 1715.2 µs | ingest= 753.4 sim= 92.6 export= 61.5 diag= 0.0 µs | exported=4265.19 MB acks=52515000
|
||||
tick= 5000 | entities= 150000 (sensor_active= 67700, alerts= 334, act=15000) | faults=6786973 lockouts= 0 | rss= 0.0 MB | tick_mean= 1726.7 µs | ingest= 755.2 sim= 93.0 export= 61.8 diag= 0.0 µs | exported=5483.51 MB acks=67515000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 8.604 s
|
||||
Sustained tick rate: 581.1 Hz
|
||||
Per-tick mean (wall): 171.6 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 754.2
|
||||
SimulationSystem: 92.5
|
||||
ExportSystem: 61.7
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 7460636
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 6091.45 MB
|
||||
Acks processed: 75000000
|
||||
Alerts seen: 1543036
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results/csv/entities_200000.txt
Normal file
35
results/csv/entities_200000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=200000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=140000 EventAsset=40000 ActuatorAsset=20000 total=200000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 200000 (sensor_active=176493, alerts= 0, act=20000) | faults= 3507 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 415.0 sim= 160.0 export= 84.0 diag= 0.0 µs | exported=1.62 MB acks=20000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 200000 (sensor_active= 90145, alerts= 390, act=20000) | faults=1847083 lockouts= 0 | rss= 0.0 MB | tick_mean= 2413.0 µs | ingest=1003.2 sim= 125.4 export= 83.3 diag= 0.0 µs | exported=813.81 MB acks=10020000
|
||||
tick= 2000 | entities= 200000 (sensor_active= 90392, alerts= 385, act=20000) | faults=3647521 lockouts= 0 | rss= 0.0 MB | tick_mean= 2409.9 µs | ingest=1003.2 sim= 125.4 export= 83.1 diag= 0.0 µs | exported=2438.20 MB acks=30020000
|
||||
tick= 3000 | entities= 200000 (sensor_active= 90372, alerts= 391, act=20000) | faults=5447700 lockouts= 0 | rss= 0.0 MB | tick_mean= 2380.4 µs | ingest= 998.3 sim= 124.5 export= 82.8 diag= 0.0 µs | exported=4062.57 MB acks=50020000
|
||||
tick= 4000 | entities= 200000 (sensor_active= 89452, alerts= 451, act=20000) | faults=7247668 lockouts= 0 | rss= 0.0 MB | tick_mean= 2380.1 µs | ingest= 998.7 sim= 124.7 export= 82.5 diag= 0.0 µs | exported=5686.95 MB acks=70020000
|
||||
tick= 5000 | entities= 200000 (sensor_active= 89914, alerts= 424, act=20000) | faults=9047286 lockouts= 0 | rss= 0.0 MB | tick_mean= 2386.7 µs | ingest= 999.0 sim= 124.7 export= 82.8 diag= 0.0 µs | exported=7311.35 MB acks=90020000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 11.966 s
|
||||
Sustained tick rate: 417.9 Hz
|
||||
Per-tick mean (wall): 239.4 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 1001.3
|
||||
SimulationSystem: 125.2
|
||||
ExportSystem: 83.1
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 9946420
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 8121.92 MB
|
||||
Acks processed: 100000000
|
||||
Alerts seen: 2056796
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results/csv/entities_25000.txt
Normal file
35
results/csv/entities_25000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=25000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=17500 EventAsset=5000 ActuatorAsset=2500 total=25000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 25000 (sensor_active= 22049, alerts= 0, act= 2500) | faults= 451 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 67.0 sim= 19.0 export= 11.0 diag= 0.0 µs | exported=0.20 MB acks=2500
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 25000 (sensor_active= 11440, alerts= 49, act= 2500) | faults=231419 lockouts= 0 | rss= 0.0 MB | tick_mean= 274.4 µs | ingest= 125.7 sim= 15.0 export= 9.9 diag= 0.0 µs | exported=101.74 MB acks=1252500
|
||||
tick= 2000 | entities= 25000 (sensor_active= 11301, alerts= 43, act= 2500) | faults=456552 lockouts= 0 | rss= 0.0 MB | tick_mean= 274.6 µs | ingest= 125.8 sim= 15.1 export= 9.9 diag= 0.0 µs | exported=304.78 MB acks=3752500
|
||||
tick= 3000 | entities= 25000 (sensor_active= 11421, alerts= 58, act= 2500) | faults=681247 lockouts= 0 | rss= 0.0 MB | tick_mean= 276.1 µs | ingest= 126.4 sim= 15.1 export= 10.0 diag= 0.0 µs | exported=507.82 MB acks=6252500
|
||||
tick= 4000 | entities= 25000 (sensor_active= 11157, alerts= 48, act= 2500) | faults=906865 lockouts= 0 | rss= 0.0 MB | tick_mean= 274.5 µs | ingest= 125.7 sim= 15.1 export= 9.9 diag= 0.0 µs | exported=710.88 MB acks=8752500
|
||||
tick= 5000 | entities= 25000 (sensor_active= 11216, alerts= 49, act= 2500) | faults=1131163 lockouts= 0 | rss= 0.0 MB | tick_mean= 274.9 µs | ingest= 125.9 sim= 15.0 export= 9.9 diag= 0.0 µs | exported=913.91 MB acks=11252500
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 1.378 s
|
||||
Sustained tick rate: 3629.5 Hz
|
||||
Per-tick mean (wall): 27.5 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 125.6
|
||||
SimulationSystem: 15.0
|
||||
ExportSystem: 9.9
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 1243639
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 1015.22 MB
|
||||
Acks processed: 12500000
|
||||
Alerts seen: 254654
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results/csv/entities_50000.txt
Normal file
35
results/csv/entities_50000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=50000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=35000 EventAsset=10000 ActuatorAsset=5000 total=50000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 50000 (sensor_active= 44082, alerts= 0, act= 5000) | faults= 918 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 104.0 sim= 34.0 export= 18.0 diag= 0.0 µs | exported=0.41 MB acks=5000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 50000 (sensor_active= 22364, alerts= 118, act= 5000) | faults=462345 lockouts= 0 | rss= 0.0 MB | tick_mean= 548.8 µs | ingest= 254.6 sim= 30.7 export= 20.0 diag= 0.0 µs | exported=203.46 MB acks=2505000
|
||||
tick= 2000 | entities= 50000 (sensor_active= 22510, alerts= 97, act= 5000) | faults=912440 lockouts= 0 | rss= 0.0 MB | tick_mean= 546.7 µs | ingest= 253.0 sim= 30.3 export= 19.9 diag= 0.0 µs | exported=609.56 MB acks=7505000
|
||||
tick= 3000 | entities= 50000 (sensor_active= 22512, alerts= 90, act= 5000) | faults=1361728 lockouts= 0 | rss= 0.0 MB | tick_mean= 549.3 µs | ingest= 254.3 sim= 30.6 export= 20.1 diag= 0.0 µs | exported=1015.66 MB acks=12505000
|
||||
tick= 4000 | entities= 50000 (sensor_active= 22519, alerts= 98, act= 5000) | faults=1812084 lockouts= 0 | rss= 0.0 MB | tick_mean= 549.2 µs | ingest= 254.1 sim= 30.5 export= 20.0 diag= 0.0 µs | exported=1421.74 MB acks=17505000
|
||||
tick= 5000 | entities= 50000 (sensor_active= 22355, alerts= 101, act= 5000) | faults=2261407 lockouts= 0 | rss= 0.0 MB | tick_mean= 545.8 µs | ingest= 252.6 sim= 30.4 export= 19.9 diag= 0.0 µs | exported=1827.82 MB acks=22505000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 2.743 s
|
||||
Sustained tick rate: 1822.8 Hz
|
||||
Per-tick mean (wall): 54.9 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 254.0
|
||||
SimulationSystem: 30.5
|
||||
ExportSystem: 19.9
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 2486121
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 2030.46 MB
|
||||
Acks processed: 25000000
|
||||
Alerts seen: 511654
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results/csv/entities_75000.txt
Normal file
35
results/csv/entities_75000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=75000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=52500 EventAsset=15000 ActuatorAsset=7500 total=75000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 75000 (sensor_active= 66146, alerts= 0, act= 7500) | faults= 1354 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 188.0 sim= 62.0 export= 32.0 diag= 0.0 µs | exported=0.61 MB acks=7500
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 75000 (sensor_active= 33877, alerts= 133, act= 7500) | faults=693165 lockouts= 0 | rss= 0.0 MB | tick_mean= 818.6 µs | ingest= 378.8 sim= 45.8 export= 30.8 diag= 0.0 µs | exported=305.18 MB acks=3757500
|
||||
tick= 2000 | entities= 75000 (sensor_active= 33696, alerts= 163, act= 7500) | faults=1367793 lockouts= 0 | rss= 0.0 MB | tick_mean= 817.4 µs | ingest= 377.4 sim= 45.7 export= 30.6 diag= 0.0 µs | exported=914.34 MB acks=11257500
|
||||
tick= 3000 | entities= 75000 (sensor_active= 33889, alerts= 145, act= 7500) | faults=2042643 lockouts= 0 | rss= 0.0 MB | tick_mean= 817.6 µs | ingest= 377.7 sim= 45.8 export= 30.6 diag= 0.0 µs | exported=1523.51 MB acks=18757500
|
||||
tick= 4000 | entities= 75000 (sensor_active= 33657, alerts= 169, act= 7500) | faults=2717674 lockouts= 0 | rss= 0.0 MB | tick_mean= 815.9 µs | ingest= 376.7 sim= 45.6 export= 30.5 diag= 0.0 µs | exported=2132.66 MB acks=26257500
|
||||
tick= 5000 | entities= 75000 (sensor_active= 33573, alerts= 162, act= 7500) | faults=3393495 lockouts= 0 | rss= 0.0 MB | tick_mean= 820.1 µs | ingest= 377.7 sim= 45.7 export= 30.7 diag= 0.0 µs | exported=2741.78 MB acks=33757500
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 4.094 s
|
||||
Sustained tick rate: 1221.3 Hz
|
||||
Per-tick mean (wall): 82.0 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 377.6
|
||||
SimulationSystem: 45.7
|
||||
ExportSystem: 30.6
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 3730093
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 3045.72 MB
|
||||
Acks processed: 37500000
|
||||
Alerts seen: 771425
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
8
results/final_table.csv
Normal file
8
results/final_table.csv
Normal file
@@ -0,0 +1,8 @@
|
||||
entities,ticks,wall_s,hz,per_tick_us,ingest_us,sim_us,export_us,diag_us,sensor_faults,actuator_lockouts,exported_mb,acks,alerts,rss_mb
|
||||
10000,5000,,,,48.8,5.9,3.9,0.0,498016,0,,5000000,104943,
|
||||
25000,5000,,,,125.6,15.0,9.9,0.0,1243639,0,,12500000,254654,
|
||||
50000,5000,,,,254.0,30.5,19.9,0.0,2486121,0,,25000000,511654,
|
||||
75000,5000,,,,377.6,45.7,30.6,0.0,3730093,0,,37500000,771425,
|
||||
100000,5000,,,,504.2,61.8,41.0,0.0,4974449,0,,50000000,1028407,
|
||||
150000,5000,,,,754.2,92.5,61.7,0.0,7460636,0,,75000000,1543036,
|
||||
200000,5000,,,,1001.3,125.2,83.1,0.0,9946420,0,,100000000,2056796,
|
||||
|
35
results/raw_10000.txt
Normal file
35
results/raw_10000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=10000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=7000 EventAsset=2000 ActuatorAsset=1000 total=10000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 10000 (sensor_active= 8817, alerts= 0, act= 1000) | faults= 183 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 94.0 sim= 20.0 export= 11.0 diag= 0.0 µs | exported=0.08 MB acks=1000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 10000 (sensor_active= 4488, alerts= 23, act= 1000) | faults= 92482 lockouts= 0 | rss= 0.0 MB | tick_mean= 105.6 µs | ingest= 48.8 sim= 6.0 export= 3.9 diag= 0.0 µs | exported=40.70 MB acks=501000
|
||||
tick= 2000 | entities= 10000 (sensor_active= 4425, alerts= 23, act= 1000) | faults=182979 lockouts= 0 | rss= 0.0 MB | tick_mean= 105.6 µs | ingest= 48.6 sim= 5.9 export= 3.9 diag= 0.0 µs | exported=121.92 MB acks=1501000
|
||||
tick= 3000 | entities= 10000 (sensor_active= 4507, alerts= 27, act= 1000) | faults=273085 lockouts= 0 | rss= 0.0 MB | tick_mean= 105.2 µs | ingest= 48.6 sim= 5.9 export= 3.9 diag= 0.0 µs | exported=203.15 MB acks=2501000
|
||||
tick= 4000 | entities= 10000 (sensor_active= 4502, alerts= 15, act= 1000) | faults=363376 lockouts= 0 | rss= 0.0 MB | tick_mean= 105.6 µs | ingest= 48.8 sim= 5.9 export= 3.9 diag= 0.0 µs | exported=284.37 MB acks=3501000
|
||||
tick= 5000 | entities= 10000 (sensor_active= 4527, alerts= 24, act= 1000) | faults=453183 lockouts= 0 | rss= 0.0 MB | tick_mean= 105.8 µs | ingest= 48.9 sim= 5.9 export= 3.9 diag= 0.0 µs | exported=365.59 MB acks=4501000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 0.531 s
|
||||
Sustained tick rate: 9424.5 Hz
|
||||
Per-tick mean (wall): 10.6 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 48.8
|
||||
SimulationSystem: 5.9
|
||||
ExportSystem: 3.9
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 498016
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 406.11 MB
|
||||
Acks processed: 5000000
|
||||
Alerts seen: 104943
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results/raw_100000.txt
Normal file
35
results/raw_100000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=100000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=70000 EventAsset=20000 ActuatorAsset=10000 total=100000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 100000 (sensor_active= 88228, alerts= 0, act=10000) | faults= 1772 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 202.0 sim= 75.0 export= 41.0 diag= 0.0 µs | exported=0.81 MB acks=10000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 100000 (sensor_active= 45396, alerts= 218, act=10000) | faults=924085 lockouts= 0 | rss= 0.0 MB | tick_mean= 1101.8 µs | ingest= 500.9 sim= 61.2 export= 40.6 diag= 0.0 µs | exported=406.92 MB acks=5010000
|
||||
tick= 2000 | entities= 100000 (sensor_active= 44998, alerts= 212, act=10000) | faults=1823730 lockouts= 0 | rss= 0.0 MB | tick_mean= 1105.1 µs | ingest= 501.0 sim= 61.1 export= 40.6 diag= 0.0 µs | exported=1219.14 MB acks=15010000
|
||||
tick= 3000 | entities= 100000 (sensor_active= 45132, alerts= 187, act=10000) | faults=2723608 lockouts= 0 | rss= 0.0 MB | tick_mean= 1114.2 µs | ingest= 504.7 sim= 61.5 export= 40.8 diag= 0.0 µs | exported=2031.31 MB acks=25010000
|
||||
tick= 4000 | entities= 100000 (sensor_active= 45039, alerts= 226, act=10000) | faults=3624295 lockouts= 0 | rss= 0.0 MB | tick_mean= 1112.0 µs | ingest= 505.0 sim= 61.7 export= 40.9 diag= 0.0 µs | exported=2843.48 MB acks=35010000
|
||||
tick= 5000 | entities= 100000 (sensor_active= 45069, alerts= 206, act=10000) | faults=4525217 lockouts= 0 | rss= 0.0 MB | tick_mean= 1112.9 µs | ingest= 504.7 sim= 61.8 export= 40.9 diag= 0.0 µs | exported=3655.68 MB acks=45010000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 5.555 s
|
||||
Sustained tick rate: 900.2 Hz
|
||||
Per-tick mean (wall): 111.2 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 504.2
|
||||
SimulationSystem: 61.8
|
||||
ExportSystem: 41.0
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 4974449
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 4060.96 MB
|
||||
Acks processed: 50000000
|
||||
Alerts seen: 1028407
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results/raw_150000.txt
Normal file
35
results/raw_150000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=150000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=105000 EventAsset=30000 ActuatorAsset=15000 total=150000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 150000 (sensor_active=132379, alerts= 0, act=15000) | faults= 2621 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 306.0 sim= 113.0 export= 61.0 diag= 0.0 µs | exported=1.22 MB acks=15000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 150000 (sensor_active= 67721, alerts= 326, act=15000) | faults=1385323 lockouts= 0 | rss= 0.0 MB | tick_mean= 1717.3 µs | ingest= 755.7 sim= 92.9 export= 61.8 diag= 0.0 µs | exported=610.34 MB acks=7515000
|
||||
tick= 2000 | entities= 150000 (sensor_active= 67238, alerts= 278, act=15000) | faults=2736064 lockouts= 0 | rss= 0.0 MB | tick_mean= 1721.7 µs | ingest= 755.2 sim= 93.0 export= 61.8 diag= 0.0 µs | exported=1828.59 MB acks=22515000
|
||||
tick= 3000 | entities= 150000 (sensor_active= 67728, alerts= 330, act=15000) | faults=4087020 lockouts= 0 | rss= 0.0 MB | tick_mean= 1719.6 µs | ingest= 753.9 sim= 93.0 export= 61.5 diag= 0.0 µs | exported=3046.89 MB acks=37515000
|
||||
tick= 4000 | entities= 150000 (sensor_active= 67533, alerts= 323, act=15000) | faults=5437256 lockouts= 0 | rss= 0.0 MB | tick_mean= 1715.2 µs | ingest= 753.4 sim= 92.6 export= 61.5 diag= 0.0 µs | exported=4265.19 MB acks=52515000
|
||||
tick= 5000 | entities= 150000 (sensor_active= 67700, alerts= 334, act=15000) | faults=6786973 lockouts= 0 | rss= 0.0 MB | tick_mean= 1726.7 µs | ingest= 755.2 sim= 93.0 export= 61.8 diag= 0.0 µs | exported=5483.51 MB acks=67515000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 8.604 s
|
||||
Sustained tick rate: 581.1 Hz
|
||||
Per-tick mean (wall): 171.6 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 754.2
|
||||
SimulationSystem: 92.5
|
||||
ExportSystem: 61.7
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 7460636
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 6091.45 MB
|
||||
Acks processed: 75000000
|
||||
Alerts seen: 1543036
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results/raw_200000.txt
Normal file
35
results/raw_200000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=200000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=140000 EventAsset=40000 ActuatorAsset=20000 total=200000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 200000 (sensor_active=176493, alerts= 0, act=20000) | faults= 3507 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 415.0 sim= 160.0 export= 84.0 diag= 0.0 µs | exported=1.62 MB acks=20000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 200000 (sensor_active= 90145, alerts= 390, act=20000) | faults=1847083 lockouts= 0 | rss= 0.0 MB | tick_mean= 2413.0 µs | ingest=1003.2 sim= 125.4 export= 83.3 diag= 0.0 µs | exported=813.81 MB acks=10020000
|
||||
tick= 2000 | entities= 200000 (sensor_active= 90392, alerts= 385, act=20000) | faults=3647521 lockouts= 0 | rss= 0.0 MB | tick_mean= 2409.9 µs | ingest=1003.2 sim= 125.4 export= 83.1 diag= 0.0 µs | exported=2438.20 MB acks=30020000
|
||||
tick= 3000 | entities= 200000 (sensor_active= 90372, alerts= 391, act=20000) | faults=5447700 lockouts= 0 | rss= 0.0 MB | tick_mean= 2380.4 µs | ingest= 998.3 sim= 124.5 export= 82.8 diag= 0.0 µs | exported=4062.57 MB acks=50020000
|
||||
tick= 4000 | entities= 200000 (sensor_active= 89452, alerts= 451, act=20000) | faults=7247668 lockouts= 0 | rss= 0.0 MB | tick_mean= 2380.1 µs | ingest= 998.7 sim= 124.7 export= 82.5 diag= 0.0 µs | exported=5686.95 MB acks=70020000
|
||||
tick= 5000 | entities= 200000 (sensor_active= 89914, alerts= 424, act=20000) | faults=9047286 lockouts= 0 | rss= 0.0 MB | tick_mean= 2386.7 µs | ingest= 999.0 sim= 124.7 export= 82.8 diag= 0.0 µs | exported=7311.35 MB acks=90020000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 11.966 s
|
||||
Sustained tick rate: 417.9 Hz
|
||||
Per-tick mean (wall): 239.4 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 1001.3
|
||||
SimulationSystem: 125.2
|
||||
ExportSystem: 83.1
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 9946420
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 8121.92 MB
|
||||
Acks processed: 100000000
|
||||
Alerts seen: 2056796
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results/raw_25000.txt
Normal file
35
results/raw_25000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=25000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=17500 EventAsset=5000 ActuatorAsset=2500 total=25000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 25000 (sensor_active= 22049, alerts= 0, act= 2500) | faults= 451 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 67.0 sim= 19.0 export= 11.0 diag= 0.0 µs | exported=0.20 MB acks=2500
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 25000 (sensor_active= 11440, alerts= 49, act= 2500) | faults=231419 lockouts= 0 | rss= 0.0 MB | tick_mean= 274.4 µs | ingest= 125.7 sim= 15.0 export= 9.9 diag= 0.0 µs | exported=101.74 MB acks=1252500
|
||||
tick= 2000 | entities= 25000 (sensor_active= 11301, alerts= 43, act= 2500) | faults=456552 lockouts= 0 | rss= 0.0 MB | tick_mean= 274.6 µs | ingest= 125.8 sim= 15.1 export= 9.9 diag= 0.0 µs | exported=304.78 MB acks=3752500
|
||||
tick= 3000 | entities= 25000 (sensor_active= 11421, alerts= 58, act= 2500) | faults=681247 lockouts= 0 | rss= 0.0 MB | tick_mean= 276.1 µs | ingest= 126.4 sim= 15.1 export= 10.0 diag= 0.0 µs | exported=507.82 MB acks=6252500
|
||||
tick= 4000 | entities= 25000 (sensor_active= 11157, alerts= 48, act= 2500) | faults=906865 lockouts= 0 | rss= 0.0 MB | tick_mean= 274.5 µs | ingest= 125.7 sim= 15.1 export= 9.9 diag= 0.0 µs | exported=710.88 MB acks=8752500
|
||||
tick= 5000 | entities= 25000 (sensor_active= 11216, alerts= 49, act= 2500) | faults=1131163 lockouts= 0 | rss= 0.0 MB | tick_mean= 274.9 µs | ingest= 125.9 sim= 15.0 export= 9.9 diag= 0.0 µs | exported=913.91 MB acks=11252500
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 1.378 s
|
||||
Sustained tick rate: 3629.5 Hz
|
||||
Per-tick mean (wall): 27.5 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 125.6
|
||||
SimulationSystem: 15.0
|
||||
ExportSystem: 9.9
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 1243639
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 1015.22 MB
|
||||
Acks processed: 12500000
|
||||
Alerts seen: 254654
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results/raw_50000.txt
Normal file
35
results/raw_50000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=50000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=35000 EventAsset=10000 ActuatorAsset=5000 total=50000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 50000 (sensor_active= 44082, alerts= 0, act= 5000) | faults= 918 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 104.0 sim= 34.0 export= 18.0 diag= 0.0 µs | exported=0.41 MB acks=5000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 50000 (sensor_active= 22364, alerts= 118, act= 5000) | faults=462345 lockouts= 0 | rss= 0.0 MB | tick_mean= 548.8 µs | ingest= 254.6 sim= 30.7 export= 20.0 diag= 0.0 µs | exported=203.46 MB acks=2505000
|
||||
tick= 2000 | entities= 50000 (sensor_active= 22510, alerts= 97, act= 5000) | faults=912440 lockouts= 0 | rss= 0.0 MB | tick_mean= 546.7 µs | ingest= 253.0 sim= 30.3 export= 19.9 diag= 0.0 µs | exported=609.56 MB acks=7505000
|
||||
tick= 3000 | entities= 50000 (sensor_active= 22512, alerts= 90, act= 5000) | faults=1361728 lockouts= 0 | rss= 0.0 MB | tick_mean= 549.3 µs | ingest= 254.3 sim= 30.6 export= 20.1 diag= 0.0 µs | exported=1015.66 MB acks=12505000
|
||||
tick= 4000 | entities= 50000 (sensor_active= 22519, alerts= 98, act= 5000) | faults=1812084 lockouts= 0 | rss= 0.0 MB | tick_mean= 549.2 µs | ingest= 254.1 sim= 30.5 export= 20.0 diag= 0.0 µs | exported=1421.74 MB acks=17505000
|
||||
tick= 5000 | entities= 50000 (sensor_active= 22355, alerts= 101, act= 5000) | faults=2261407 lockouts= 0 | rss= 0.0 MB | tick_mean= 545.8 µs | ingest= 252.6 sim= 30.4 export= 19.9 diag= 0.0 µs | exported=1827.82 MB acks=22505000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 2.743 s
|
||||
Sustained tick rate: 1822.8 Hz
|
||||
Per-tick mean (wall): 54.9 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 254.0
|
||||
SimulationSystem: 30.5
|
||||
ExportSystem: 19.9
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 2486121
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 2030.46 MB
|
||||
Acks processed: 25000000
|
||||
Alerts seen: 511654
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results/raw_75000.txt
Normal file
35
results/raw_75000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=75000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=52500 EventAsset=15000 ActuatorAsset=7500 total=75000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 75000 (sensor_active= 66146, alerts= 0, act= 7500) | faults= 1354 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 188.0 sim= 62.0 export= 32.0 diag= 0.0 µs | exported=0.61 MB acks=7500
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 75000 (sensor_active= 33877, alerts= 133, act= 7500) | faults=693165 lockouts= 0 | rss= 0.0 MB | tick_mean= 818.6 µs | ingest= 378.8 sim= 45.8 export= 30.8 diag= 0.0 µs | exported=305.18 MB acks=3757500
|
||||
tick= 2000 | entities= 75000 (sensor_active= 33696, alerts= 163, act= 7500) | faults=1367793 lockouts= 0 | rss= 0.0 MB | tick_mean= 817.4 µs | ingest= 377.4 sim= 45.7 export= 30.6 diag= 0.0 µs | exported=914.34 MB acks=11257500
|
||||
tick= 3000 | entities= 75000 (sensor_active= 33889, alerts= 145, act= 7500) | faults=2042643 lockouts= 0 | rss= 0.0 MB | tick_mean= 817.6 µs | ingest= 377.7 sim= 45.8 export= 30.6 diag= 0.0 µs | exported=1523.51 MB acks=18757500
|
||||
tick= 4000 | entities= 75000 (sensor_active= 33657, alerts= 169, act= 7500) | faults=2717674 lockouts= 0 | rss= 0.0 MB | tick_mean= 815.9 µs | ingest= 376.7 sim= 45.6 export= 30.5 diag= 0.0 µs | exported=2132.66 MB acks=26257500
|
||||
tick= 5000 | entities= 75000 (sensor_active= 33573, alerts= 162, act= 7500) | faults=3393495 lockouts= 0 | rss= 0.0 MB | tick_mean= 820.1 µs | ingest= 377.7 sim= 45.7 export= 30.7 diag= 0.0 µs | exported=2741.78 MB acks=33757500
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 4.094 s
|
||||
Sustained tick rate: 1221.3 Hz
|
||||
Per-tick mean (wall): 82.0 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 377.6
|
||||
SimulationSystem: 45.7
|
||||
ExportSystem: 30.6
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 3730093
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 3045.72 MB
|
||||
Acks processed: 37500000
|
||||
Alerts seen: 771425
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
271
results/summary.txt
Normal file
271
results/summary.txt
Normal file
@@ -0,0 +1,271 @@
|
||||
ECS DT Benchmark Sweep — Mon Apr 20 21:17:09 UTC 2026
|
||||
=== System Information ===
|
||||
Date: 2026-04-20 21:17:09 UTC
|
||||
OS: Darwin 25.4.0
|
||||
Arch: arm64
|
||||
Target CPU: apple-m1
|
||||
Rust: rustc 1.94.0 (4a4ef493e 2026-03-02)
|
||||
Cargo: cargo 1.94.0 (85eff7c80 2026-01-15)
|
||||
|
||||
Apple M4 Max
|
||||
Memory: 128.0 GB
|
||||
|
||||
|
||||
=== entities=10000 ===
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=10000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=7000 EventAsset=2000 ActuatorAsset=1000 total=10000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 10000 (sensor_active= 8817, alerts= 0, act= 1000) | faults= 183 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 94.0 sim= 20.0 export= 11.0 diag= 0.0 µs | exported=0.08 MB acks=1000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 10000 (sensor_active= 4488, alerts= 23, act= 1000) | faults= 92482 lockouts= 0 | rss= 0.0 MB | tick_mean= 105.6 µs | ingest= 48.8 sim= 6.0 export= 3.9 diag= 0.0 µs | exported=40.70 MB acks=501000
|
||||
tick= 2000 | entities= 10000 (sensor_active= 4425, alerts= 23, act= 1000) | faults=182979 lockouts= 0 | rss= 0.0 MB | tick_mean= 105.6 µs | ingest= 48.6 sim= 5.9 export= 3.9 diag= 0.0 µs | exported=121.92 MB acks=1501000
|
||||
tick= 3000 | entities= 10000 (sensor_active= 4507, alerts= 27, act= 1000) | faults=273085 lockouts= 0 | rss= 0.0 MB | tick_mean= 105.2 µs | ingest= 48.6 sim= 5.9 export= 3.9 diag= 0.0 µs | exported=203.15 MB acks=2501000
|
||||
tick= 4000 | entities= 10000 (sensor_active= 4502, alerts= 15, act= 1000) | faults=363376 lockouts= 0 | rss= 0.0 MB | tick_mean= 105.6 µs | ingest= 48.8 sim= 5.9 export= 3.9 diag= 0.0 µs | exported=284.37 MB acks=3501000
|
||||
tick= 5000 | entities= 10000 (sensor_active= 4527, alerts= 24, act= 1000) | faults=453183 lockouts= 0 | rss= 0.0 MB | tick_mean= 105.8 µs | ingest= 48.9 sim= 5.9 export= 3.9 diag= 0.0 µs | exported=365.59 MB acks=4501000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 0.531 s
|
||||
Sustained tick rate: 9424.5 Hz
|
||||
Per-tick mean (wall): 10.6 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 48.8
|
||||
SimulationSystem: 5.9
|
||||
ExportSystem: 3.9
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 498016
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 406.11 MB
|
||||
Acks processed: 5000000
|
||||
Alerts seen: 104943
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
|
||||
=== entities=25000 ===
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=25000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=17500 EventAsset=5000 ActuatorAsset=2500 total=25000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 25000 (sensor_active= 22049, alerts= 0, act= 2500) | faults= 451 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 67.0 sim= 19.0 export= 11.0 diag= 0.0 µs | exported=0.20 MB acks=2500
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 25000 (sensor_active= 11440, alerts= 49, act= 2500) | faults=231419 lockouts= 0 | rss= 0.0 MB | tick_mean= 274.4 µs | ingest= 125.7 sim= 15.0 export= 9.9 diag= 0.0 µs | exported=101.74 MB acks=1252500
|
||||
tick= 2000 | entities= 25000 (sensor_active= 11301, alerts= 43, act= 2500) | faults=456552 lockouts= 0 | rss= 0.0 MB | tick_mean= 274.6 µs | ingest= 125.8 sim= 15.1 export= 9.9 diag= 0.0 µs | exported=304.78 MB acks=3752500
|
||||
tick= 3000 | entities= 25000 (sensor_active= 11421, alerts= 58, act= 2500) | faults=681247 lockouts= 0 | rss= 0.0 MB | tick_mean= 276.1 µs | ingest= 126.4 sim= 15.1 export= 10.0 diag= 0.0 µs | exported=507.82 MB acks=6252500
|
||||
tick= 4000 | entities= 25000 (sensor_active= 11157, alerts= 48, act= 2500) | faults=906865 lockouts= 0 | rss= 0.0 MB | tick_mean= 274.5 µs | ingest= 125.7 sim= 15.1 export= 9.9 diag= 0.0 µs | exported=710.88 MB acks=8752500
|
||||
tick= 5000 | entities= 25000 (sensor_active= 11216, alerts= 49, act= 2500) | faults=1131163 lockouts= 0 | rss= 0.0 MB | tick_mean= 274.9 µs | ingest= 125.9 sim= 15.0 export= 9.9 diag= 0.0 µs | exported=913.91 MB acks=11252500
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 1.378 s
|
||||
Sustained tick rate: 3629.5 Hz
|
||||
Per-tick mean (wall): 27.5 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 125.6
|
||||
SimulationSystem: 15.0
|
||||
ExportSystem: 9.9
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 1243639
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 1015.22 MB
|
||||
Acks processed: 12500000
|
||||
Alerts seen: 254654
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
|
||||
=== entities=50000 ===
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=50000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=35000 EventAsset=10000 ActuatorAsset=5000 total=50000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 50000 (sensor_active= 44082, alerts= 0, act= 5000) | faults= 918 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 104.0 sim= 34.0 export= 18.0 diag= 0.0 µs | exported=0.41 MB acks=5000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 50000 (sensor_active= 22364, alerts= 118, act= 5000) | faults=462345 lockouts= 0 | rss= 0.0 MB | tick_mean= 548.8 µs | ingest= 254.6 sim= 30.7 export= 20.0 diag= 0.0 µs | exported=203.46 MB acks=2505000
|
||||
tick= 2000 | entities= 50000 (sensor_active= 22510, alerts= 97, act= 5000) | faults=912440 lockouts= 0 | rss= 0.0 MB | tick_mean= 546.7 µs | ingest= 253.0 sim= 30.3 export= 19.9 diag= 0.0 µs | exported=609.56 MB acks=7505000
|
||||
tick= 3000 | entities= 50000 (sensor_active= 22512, alerts= 90, act= 5000) | faults=1361728 lockouts= 0 | rss= 0.0 MB | tick_mean= 549.3 µs | ingest= 254.3 sim= 30.6 export= 20.1 diag= 0.0 µs | exported=1015.66 MB acks=12505000
|
||||
tick= 4000 | entities= 50000 (sensor_active= 22519, alerts= 98, act= 5000) | faults=1812084 lockouts= 0 | rss= 0.0 MB | tick_mean= 549.2 µs | ingest= 254.1 sim= 30.5 export= 20.0 diag= 0.0 µs | exported=1421.74 MB acks=17505000
|
||||
tick= 5000 | entities= 50000 (sensor_active= 22355, alerts= 101, act= 5000) | faults=2261407 lockouts= 0 | rss= 0.0 MB | tick_mean= 545.8 µs | ingest= 252.6 sim= 30.4 export= 19.9 diag= 0.0 µs | exported=1827.82 MB acks=22505000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 2.743 s
|
||||
Sustained tick rate: 1822.8 Hz
|
||||
Per-tick mean (wall): 54.9 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 254.0
|
||||
SimulationSystem: 30.5
|
||||
ExportSystem: 19.9
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 2486121
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 2030.46 MB
|
||||
Acks processed: 25000000
|
||||
Alerts seen: 511654
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
|
||||
=== entities=75000 ===
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=75000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=52500 EventAsset=15000 ActuatorAsset=7500 total=75000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 75000 (sensor_active= 66146, alerts= 0, act= 7500) | faults= 1354 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 188.0 sim= 62.0 export= 32.0 diag= 0.0 µs | exported=0.61 MB acks=7500
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 75000 (sensor_active= 33877, alerts= 133, act= 7500) | faults=693165 lockouts= 0 | rss= 0.0 MB | tick_mean= 818.6 µs | ingest= 378.8 sim= 45.8 export= 30.8 diag= 0.0 µs | exported=305.18 MB acks=3757500
|
||||
tick= 2000 | entities= 75000 (sensor_active= 33696, alerts= 163, act= 7500) | faults=1367793 lockouts= 0 | rss= 0.0 MB | tick_mean= 817.4 µs | ingest= 377.4 sim= 45.7 export= 30.6 diag= 0.0 µs | exported=914.34 MB acks=11257500
|
||||
tick= 3000 | entities= 75000 (sensor_active= 33889, alerts= 145, act= 7500) | faults=2042643 lockouts= 0 | rss= 0.0 MB | tick_mean= 817.6 µs | ingest= 377.7 sim= 45.8 export= 30.6 diag= 0.0 µs | exported=1523.51 MB acks=18757500
|
||||
tick= 4000 | entities= 75000 (sensor_active= 33657, alerts= 169, act= 7500) | faults=2717674 lockouts= 0 | rss= 0.0 MB | tick_mean= 815.9 µs | ingest= 376.7 sim= 45.6 export= 30.5 diag= 0.0 µs | exported=2132.66 MB acks=26257500
|
||||
tick= 5000 | entities= 75000 (sensor_active= 33573, alerts= 162, act= 7500) | faults=3393495 lockouts= 0 | rss= 0.0 MB | tick_mean= 820.1 µs | ingest= 377.7 sim= 45.7 export= 30.7 diag= 0.0 µs | exported=2741.78 MB acks=33757500
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 4.094 s
|
||||
Sustained tick rate: 1221.3 Hz
|
||||
Per-tick mean (wall): 82.0 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 377.6
|
||||
SimulationSystem: 45.7
|
||||
ExportSystem: 30.6
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 3730093
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 3045.72 MB
|
||||
Acks processed: 37500000
|
||||
Alerts seen: 771425
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
|
||||
=== entities=100000 ===
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=100000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=70000 EventAsset=20000 ActuatorAsset=10000 total=100000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 100000 (sensor_active= 88228, alerts= 0, act=10000) | faults= 1772 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 202.0 sim= 75.0 export= 41.0 diag= 0.0 µs | exported=0.81 MB acks=10000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 100000 (sensor_active= 45396, alerts= 218, act=10000) | faults=924085 lockouts= 0 | rss= 0.0 MB | tick_mean= 1101.8 µs | ingest= 500.9 sim= 61.2 export= 40.6 diag= 0.0 µs | exported=406.92 MB acks=5010000
|
||||
tick= 2000 | entities= 100000 (sensor_active= 44998, alerts= 212, act=10000) | faults=1823730 lockouts= 0 | rss= 0.0 MB | tick_mean= 1105.1 µs | ingest= 501.0 sim= 61.1 export= 40.6 diag= 0.0 µs | exported=1219.14 MB acks=15010000
|
||||
tick= 3000 | entities= 100000 (sensor_active= 45132, alerts= 187, act=10000) | faults=2723608 lockouts= 0 | rss= 0.0 MB | tick_mean= 1114.2 µs | ingest= 504.7 sim= 61.5 export= 40.8 diag= 0.0 µs | exported=2031.31 MB acks=25010000
|
||||
tick= 4000 | entities= 100000 (sensor_active= 45039, alerts= 226, act=10000) | faults=3624295 lockouts= 0 | rss= 0.0 MB | tick_mean= 1112.0 µs | ingest= 505.0 sim= 61.7 export= 40.9 diag= 0.0 µs | exported=2843.48 MB acks=35010000
|
||||
tick= 5000 | entities= 100000 (sensor_active= 45069, alerts= 206, act=10000) | faults=4525217 lockouts= 0 | rss= 0.0 MB | tick_mean= 1112.9 µs | ingest= 504.7 sim= 61.8 export= 40.9 diag= 0.0 µs | exported=3655.68 MB acks=45010000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 5.555 s
|
||||
Sustained tick rate: 900.2 Hz
|
||||
Per-tick mean (wall): 111.2 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 504.2
|
||||
SimulationSystem: 61.8
|
||||
ExportSystem: 41.0
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 4974449
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 4060.96 MB
|
||||
Acks processed: 50000000
|
||||
Alerts seen: 1028407
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
|
||||
=== entities=150000 ===
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=150000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=105000 EventAsset=30000 ActuatorAsset=15000 total=150000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 150000 (sensor_active=132379, alerts= 0, act=15000) | faults= 2621 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 306.0 sim= 113.0 export= 61.0 diag= 0.0 µs | exported=1.22 MB acks=15000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 150000 (sensor_active= 67721, alerts= 326, act=15000) | faults=1385323 lockouts= 0 | rss= 0.0 MB | tick_mean= 1717.3 µs | ingest= 755.7 sim= 92.9 export= 61.8 diag= 0.0 µs | exported=610.34 MB acks=7515000
|
||||
tick= 2000 | entities= 150000 (sensor_active= 67238, alerts= 278, act=15000) | faults=2736064 lockouts= 0 | rss= 0.0 MB | tick_mean= 1721.7 µs | ingest= 755.2 sim= 93.0 export= 61.8 diag= 0.0 µs | exported=1828.59 MB acks=22515000
|
||||
tick= 3000 | entities= 150000 (sensor_active= 67728, alerts= 330, act=15000) | faults=4087020 lockouts= 0 | rss= 0.0 MB | tick_mean= 1719.6 µs | ingest= 753.9 sim= 93.0 export= 61.5 diag= 0.0 µs | exported=3046.89 MB acks=37515000
|
||||
tick= 4000 | entities= 150000 (sensor_active= 67533, alerts= 323, act=15000) | faults=5437256 lockouts= 0 | rss= 0.0 MB | tick_mean= 1715.2 µs | ingest= 753.4 sim= 92.6 export= 61.5 diag= 0.0 µs | exported=4265.19 MB acks=52515000
|
||||
tick= 5000 | entities= 150000 (sensor_active= 67700, alerts= 334, act=15000) | faults=6786973 lockouts= 0 | rss= 0.0 MB | tick_mean= 1726.7 µs | ingest= 755.2 sim= 93.0 export= 61.8 diag= 0.0 µs | exported=5483.51 MB acks=67515000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 8.604 s
|
||||
Sustained tick rate: 581.1 Hz
|
||||
Per-tick mean (wall): 171.6 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 754.2
|
||||
SimulationSystem: 92.5
|
||||
ExportSystem: 61.7
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 7460636
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 6091.45 MB
|
||||
Acks processed: 75000000
|
||||
Alerts seen: 1543036
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
|
||||
=== entities=200000 ===
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=200000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=140000 EventAsset=40000 ActuatorAsset=20000 total=200000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 200000 (sensor_active=176493, alerts= 0, act=20000) | faults= 3507 lockouts= 0 | rss= 0.0 MB | tick_mean= 0.0 µs | ingest= 415.0 sim= 160.0 export= 84.0 diag= 0.0 µs | exported=1.62 MB acks=20000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 200000 (sensor_active= 90145, alerts= 390, act=20000) | faults=1847083 lockouts= 0 | rss= 0.0 MB | tick_mean= 2413.0 µs | ingest=1003.2 sim= 125.4 export= 83.3 diag= 0.0 µs | exported=813.81 MB acks=10020000
|
||||
tick= 2000 | entities= 200000 (sensor_active= 90392, alerts= 385, act=20000) | faults=3647521 lockouts= 0 | rss= 0.0 MB | tick_mean= 2409.9 µs | ingest=1003.2 sim= 125.4 export= 83.1 diag= 0.0 µs | exported=2438.20 MB acks=30020000
|
||||
tick= 3000 | entities= 200000 (sensor_active= 90372, alerts= 391, act=20000) | faults=5447700 lockouts= 0 | rss= 0.0 MB | tick_mean= 2380.4 µs | ingest= 998.3 sim= 124.5 export= 82.8 diag= 0.0 µs | exported=4062.57 MB acks=50020000
|
||||
tick= 4000 | entities= 200000 (sensor_active= 89452, alerts= 451, act=20000) | faults=7247668 lockouts= 0 | rss= 0.0 MB | tick_mean= 2380.1 µs | ingest= 998.7 sim= 124.7 export= 82.5 diag= 0.0 µs | exported=5686.95 MB acks=70020000
|
||||
tick= 5000 | entities= 200000 (sensor_active= 89914, alerts= 424, act=20000) | faults=9047286 lockouts= 0 | rss= 0.0 MB | tick_mean= 2386.7 µs | ingest= 999.0 sim= 124.7 export= 82.8 diag= 0.0 µs | exported=7311.35 MB acks=90020000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 11.966 s
|
||||
Sustained tick rate: 417.9 Hz
|
||||
Per-tick mean (wall): 239.4 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 1001.3
|
||||
SimulationSystem: 125.2
|
||||
ExportSystem: 83.1
|
||||
DiagnosticsSystem: 0.0
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 9946420
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 8121.92 MB
|
||||
Acks processed: 100000000
|
||||
Alerts seen: 2056796
|
||||
|
||||
Memory (RSS at end): 0.0 MB
|
||||
────────────────────────────────────────────────────────
|
||||
10
results/sysinfo.txt
Normal file
10
results/sysinfo.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
=== System Information ===
|
||||
Date: 2026-04-20 21:17:09 UTC
|
||||
OS: Darwin 25.4.0
|
||||
Arch: arm64
|
||||
Target CPU: apple-m1
|
||||
Rust: rustc 1.94.0 (4a4ef493e 2026-03-02)
|
||||
Cargo: cargo 1.94.0 (85eff7c80 2026-01-15)
|
||||
|
||||
Apple M4 Max
|
||||
Memory: 128.0 GB
|
||||
35
results_rpi/csv/entities_10000.txt
Normal file
35
results_rpi/csv/entities_10000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=10000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=7000 EventAsset=2000 ActuatorAsset=1000 total=10000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 10000 (sensor_active= 8817, alerts= 0, act= 1000) | faults= 183 lockouts= 0 | rss= 4.0 MB | tick_mean= 0.0 µs | ingest= 97.0 sim= 27.0 export= 14.0 diag= 0.0 µs | exported=0.08 MB acks=1000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 10000 (sensor_active= 4488, alerts= 23, act= 1000) | faults= 92482 lockouts= 0 | rss= 6.3 MB | tick_mean= 284.8 µs | ingest= 97.1 sim= 17.1 export= 14.0 diag= 0.0 µs | exported=40.70 MB acks=501000
|
||||
tick= 2000 | entities= 10000 (sensor_active= 4425, alerts= 23, act= 1000) | faults=182979 lockouts= 0 | rss= 7.8 MB | tick_mean= 286.0 µs | ingest= 97.1 sim= 17.2 export= 14.1 diag= 0.1 µs | exported=121.92 MB acks=1501000
|
||||
tick= 3000 | entities= 10000 (sensor_active= 4507, alerts= 27, act= 1000) | faults=273085 lockouts= 0 | rss= 9.3 MB | tick_mean= 286.1 µs | ingest= 97.3 sim= 17.3 export= 14.1 diag= 0.1 µs | exported=203.15 MB acks=2501000
|
||||
tick= 4000 | entities= 10000 (sensor_active= 4502, alerts= 15, act= 1000) | faults=363376 lockouts= 0 | rss= 10.9 MB | tick_mean= 284.8 µs | ingest= 97.0 sim= 17.2 export= 14.0 diag= 0.1 µs | exported=284.37 MB acks=3501000
|
||||
tick= 5000 | entities= 10000 (sensor_active= 4527, alerts= 24, act= 1000) | faults=453183 lockouts= 0 | rss= 12.4 MB | tick_mean= 284.6 µs | ingest= 97.1 sim= 17.2 export= 14.0 diag= 0.1 µs | exported=365.59 MB acks=4501000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 1.430 s
|
||||
Sustained tick rate: 3497.7 Hz
|
||||
Per-tick mean (wall): 28.5 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 97.2
|
||||
SimulationSystem: 17.2
|
||||
ExportSystem: 14.0
|
||||
DiagnosticsSystem: 0.1
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 498016
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 406.11 MB
|
||||
Acks processed: 5000000
|
||||
Alerts seen: 104943
|
||||
|
||||
Memory (RSS at end): 13.1 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results_rpi/csv/entities_100000.txt
Normal file
35
results_rpi/csv/entities_100000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=100000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=70000 EventAsset=20000 ActuatorAsset=10000 total=100000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 100000 (sensor_active= 88228, alerts= 0, act=10000) | faults= 1772 lockouts= 0 | rss= 16.3 MB | tick_mean= 0.0 µs | ingest= 948.0 sim= 607.0 export= 157.0 diag= 0.0 µs | exported=0.81 MB acks=10000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 100000 (sensor_active= 45396, alerts= 218, act=10000) | faults=924085 lockouts= 0 | rss= 36.7 MB | tick_mean= 4126.0 µs | ingest= 986.9 sim= 218.2 export= 150.2 diag= 0.0 µs | exported=406.92 MB acks=5010000
|
||||
tick= 2000 | entities= 100000 (sensor_active= 44998, alerts= 212, act=10000) | faults=1823730 lockouts= 0 | rss= 51.9 MB | tick_mean= 4197.8 µs | ingest= 987.7 sim= 236.6 export= 152.8 diag= 0.1 µs | exported=1219.14 MB acks=15010000
|
||||
tick= 3000 | entities= 100000 (sensor_active= 45132, alerts= 187, act=10000) | faults=2723608 lockouts= 0 | rss= 67.2 MB | tick_mean= 4132.4 µs | ingest= 986.1 sim= 217.8 export= 150.1 diag= 0.1 µs | exported=2031.31 MB acks=25010000
|
||||
tick= 4000 | entities= 100000 (sensor_active= 45039, alerts= 209, act=10000) | faults=3624295 lockouts= 0 | rss= 82.4 MB | tick_mean= 4132.1 µs | ingest= 986.5 sim= 217.8 export= 150.1 diag= 0.1 µs | exported=2843.48 MB acks=35010000
|
||||
tick= 5000 | entities= 100000 (sensor_active= 45069, alerts= 187, act=10000) | faults=4525217 lockouts= 0 | rss= 97.7 MB | tick_mean= 4132.9 µs | ingest= 985.3 sim= 217.1 export= 150.0 diag= 0.1 µs | exported=3655.69 MB acks=45010000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 20.732 s
|
||||
Sustained tick rate: 241.2 Hz
|
||||
Per-tick mean (wall): 413.0 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 985.7
|
||||
SimulationSystem: 217.2
|
||||
ExportSystem: 150.1
|
||||
DiagnosticsSystem: 0.2
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 4974449
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 4060.97 MB
|
||||
Acks processed: 50000000
|
||||
Alerts seen: 1029861
|
||||
|
||||
Memory (RSS at end): 105.3 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results_rpi/csv/entities_150000.txt
Normal file
35
results_rpi/csv/entities_150000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=150000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=105000 EventAsset=30000 ActuatorAsset=15000 total=150000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 150000 (sensor_active=132379, alerts= 0, act=15000) | faults= 2621 lockouts= 0 | rss= 24.5 MB | tick_mean= 0.0 µs | ingest=1444.0 sim= 884.0 export= 251.0 diag= 0.0 µs | exported=1.22 MB acks=15000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 150000 (sensor_active= 67721, alerts= 306, act=15000) | faults=1385323 lockouts= 0 | rss= 54.3 MB | tick_mean= 6453.6 µs | ingest=1517.1 sim= 381.6 export= 226.7 diag= 0.0 µs | exported=610.34 MB acks=7515000
|
||||
tick= 2000 | entities= 150000 (sensor_active= 67238, alerts= 279, act=15000) | faults=2736064 lockouts= 0 | rss= 77.2 MB | tick_mean= 6469.3 µs | ingest=1517.2 sim= 381.6 export= 226.8 diag= 0.1 µs | exported=1828.57 MB acks=22515000
|
||||
tick= 3000 | entities= 150000 (sensor_active= 67728, alerts= 317, act=15000) | faults=4087020 lockouts= 0 | rss= 100.1 MB | tick_mean= 6473.9 µs | ingest=1519.6 sim= 382.4 export= 227.0 diag= 0.1 µs | exported=3046.87 MB acks=37515000
|
||||
tick= 4000 | entities= 150000 (sensor_active= 67533, alerts= 320, act=15000) | faults=5437256 lockouts= 0 | rss= 123.0 MB | tick_mean= 6470.4 µs | ingest=1518.3 sim= 381.8 export= 226.7 diag= 0.1 µs | exported=4265.17 MB acks=52515000
|
||||
tick= 5000 | entities= 150000 (sensor_active= 67700, alerts= 323, act=15000) | faults=6786973 lockouts= 0 | rss= 145.8 MB | tick_mean= 6470.2 µs | ingest=1518.6 sim= 382.0 export= 226.7 diag= 0.1 µs | exported=5483.48 MB acks=67515000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 32.355 s
|
||||
Sustained tick rate: 154.5 Hz
|
||||
Per-tick mean (wall): 646.7 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 1517.3
|
||||
SimulationSystem: 381.4
|
||||
ExportSystem: 226.6
|
||||
DiagnosticsSystem: 0.2
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 7460636
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 6091.41 MB
|
||||
Acks processed: 75000000
|
||||
Alerts seen: 1538845
|
||||
|
||||
Memory (RSS at end): 157.2 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results_rpi/csv/entities_200000.txt
Normal file
35
results_rpi/csv/entities_200000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=200000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=140000 EventAsset=40000 ActuatorAsset=20000 total=200000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 200000 (sensor_active=176493, alerts= 0, act=20000) | faults= 3507 lockouts= 0 | rss= 30.0 MB | tick_mean= 0.0 µs | ingest=1907.0 sim=1336.0 export= 349.0 diag= 0.0 µs | exported=1.62 MB acks=20000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 200000 (sensor_active= 90145, alerts= 405, act=20000) | faults=1847083 lockouts= 0 | rss= 69.5 MB | tick_mean= 8788.2 µs | ingest=2023.3 sim= 582.9 export= 300.9 diag= 0.0 µs | exported=813.81 MB acks=10020000
|
||||
tick= 2000 | entities= 200000 (sensor_active= 90392, alerts= 396, act=20000) | faults=3647521 lockouts= 0 | rss= 100.0 MB | tick_mean= 8805.3 µs | ingest=2023.3 sim= 582.9 export= 300.5 diag= 0.1 µs | exported=2438.20 MB acks=30020000
|
||||
tick= 3000 | entities= 200000 (sensor_active= 90372, alerts= 408, act=20000) | faults=5447700 lockouts= 0 | rss= 130.5 MB | tick_mean= 8805.5 µs | ingest=2023.7 sim= 582.7 export= 300.4 diag= 0.1 µs | exported=4062.57 MB acks=50020000
|
||||
tick= 4000 | entities= 200000 (sensor_active= 89452, alerts= 444, act=20000) | faults=7247668 lockouts= 0 | rss= 161.1 MB | tick_mean= 8808.2 µs | ingest=2024.8 sim= 583.4 export= 300.7 diag= 0.2 µs | exported=5686.94 MB acks=70020000
|
||||
tick= 5000 | entities= 200000 (sensor_active= 89914, alerts= 429, act=20000) | faults=9047286 lockouts= 0 | rss= 191.6 MB | tick_mean= 8804.6 µs | ingest=2022.3 sim= 582.4 export= 300.7 diag= 0.1 µs | exported=7311.36 MB acks=90020000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 44.034 s
|
||||
Sustained tick rate: 113.5 Hz
|
||||
Per-tick mean (wall): 880.6 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 2022.7
|
||||
SimulationSystem: 582.0
|
||||
ExportSystem: 300.7
|
||||
DiagnosticsSystem: 0.2
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 9946420
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 8121.94 MB
|
||||
Acks processed: 100000000
|
||||
Alerts seen: 2059136
|
||||
|
||||
Memory (RSS at end): 206.8 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results_rpi/csv/entities_25000.txt
Normal file
35
results_rpi/csv/entities_25000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=25000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=17500 EventAsset=5000 ActuatorAsset=2500 total=25000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 25000 (sensor_active= 22049, alerts= 0, act= 2500) | faults= 451 lockouts= 0 | rss= 6.0 MB | tick_mean= 0.0 µs | ingest= 236.0 sim= 81.0 export= 36.0 diag= 0.0 µs | exported=0.20 MB acks=2500
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 25000 (sensor_active= 11440, alerts= 49, act= 2500) | faults=231419 lockouts= 0 | rss= 11.6 MB | tick_mean= 812.9 µs | ingest= 243.3 sim= 43.2 export= 35.1 diag= 0.0 µs | exported=101.74 MB acks=1252500
|
||||
tick= 2000 | entities= 25000 (sensor_active= 11301, alerts= 43, act= 2500) | faults=456552 lockouts= 0 | rss= 15.5 MB | tick_mean= 812.1 µs | ingest= 244.1 sim= 43.2 export= 35.1 diag= 0.1 µs | exported=304.78 MB acks=3752500
|
||||
tick= 3000 | entities= 25000 (sensor_active= 11421, alerts= 58, act= 2500) | faults=681247 lockouts= 0 | rss= 19.2 MB | tick_mean= 811.6 µs | ingest= 243.6 sim= 43.0 export= 35.1 diag= 0.1 µs | exported=507.82 MB acks=6252500
|
||||
tick= 4000 | entities= 25000 (sensor_active= 11157, alerts= 48, act= 2500) | faults=906865 lockouts= 0 | rss= 23.1 MB | tick_mean= 814.2 µs | ingest= 244.0 sim= 43.3 export= 35.1 diag= 0.1 µs | exported=710.88 MB acks=8752500
|
||||
tick= 5000 | entities= 25000 (sensor_active= 11216, alerts= 49, act= 2500) | faults=1131163 lockouts= 0 | rss= 26.9 MB | tick_mean= 811.4 µs | ingest= 243.6 sim= 43.2 export= 35.1 diag= 0.1 µs | exported=913.91 MB acks=11252500
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 4.066 s
|
||||
Sustained tick rate: 1229.7 Hz
|
||||
Per-tick mean (wall): 81.3 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 244.0
|
||||
SimulationSystem: 43.2
|
||||
ExportSystem: 35.1
|
||||
DiagnosticsSystem: 0.2
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 1243639
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 1015.22 MB
|
||||
Acks processed: 12500000
|
||||
Alerts seen: 254654
|
||||
|
||||
Memory (RSS at end): 28.8 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results_rpi/csv/entities_50000.txt
Normal file
35
results_rpi/csv/entities_50000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=50000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=35000 EventAsset=10000 ActuatorAsset=5000 total=50000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 50000 (sensor_active= 44082, alerts= 0, act= 5000) | faults= 918 lockouts= 0 | rss= 9.4 MB | tick_mean= 0.0 µs | ingest= 528.0 sim= 211.0 export= 73.0 diag= 0.0 µs | exported=0.41 MB acks=5000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 50000 (sensor_active= 22364, alerts= 118, act= 5000) | faults=462345 lockouts= 0 | rss= 20.1 MB | tick_mean= 1918.9 µs | ingest= 497.0 sim= 94.6 export= 70.9 diag= 0.0 µs | exported=203.46 MB acks=2505000
|
||||
tick= 2000 | entities= 50000 (sensor_active= 22510, alerts= 97, act= 5000) | faults=912440 lockouts= 0 | rss= 27.7 MB | tick_mean= 1922.8 µs | ingest= 496.6 sim= 94.4 export= 71.0 diag= 0.1 µs | exported=609.56 MB acks=7505000
|
||||
tick= 3000 | entities= 50000 (sensor_active= 22512, alerts= 90, act= 5000) | faults=1361728 lockouts= 0 | rss= 35.3 MB | tick_mean= 1924.0 µs | ingest= 497.0 sim= 94.7 export= 71.0 diag= 0.1 µs | exported=1015.66 MB acks=12505000
|
||||
tick= 4000 | entities= 50000 (sensor_active= 22519, alerts= 98, act= 5000) | faults=1812084 lockouts= 0 | rss= 43.0 MB | tick_mean= 1922.6 µs | ingest= 496.6 sim= 94.5 export= 70.8 diag= 0.1 µs | exported=1421.74 MB acks=17505000
|
||||
tick= 5000 | entities= 50000 (sensor_active= 22355, alerts= 101, act= 5000) | faults=2261407 lockouts= 0 | rss= 50.6 MB | tick_mean= 1921.7 µs | ingest= 496.7 sim= 94.5 export= 70.9 diag= 0.1 µs | exported=1827.82 MB acks=22505000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 9.617 s
|
||||
Sustained tick rate: 519.9 Hz
|
||||
Per-tick mean (wall): 192.0 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 496.0
|
||||
SimulationSystem: 94.5
|
||||
ExportSystem: 70.8
|
||||
DiagnosticsSystem: 0.2
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 2486121
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 2030.46 MB
|
||||
Acks processed: 25000000
|
||||
Alerts seen: 511654
|
||||
|
||||
Memory (RSS at end): 54.3 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results_rpi/csv/entities_75000.txt
Normal file
35
results_rpi/csv/entities_75000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=75000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=52500 EventAsset=15000 ActuatorAsset=7500 total=75000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 75000 (sensor_active= 66146, alerts= 0, act= 7500) | faults= 1354 lockouts= 0 | rss= 13.6 MB | tick_mean= 0.0 µs | ingest= 713.0 sim= 383.0 export= 112.0 diag= 0.0 µs | exported=0.61 MB acks=7500
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 75000 (sensor_active= 33877, alerts= 142, act= 7500) | faults=693165 lockouts= 0 | rss= 28.7 MB | tick_mean= 3016.1 µs | ingest= 735.8 sim= 156.6 export= 110.8 diag= 0.0 µs | exported=305.18 MB acks=3757500
|
||||
tick= 2000 | entities= 75000 (sensor_active= 33696, alerts= 166, act= 7500) | faults=1367793 lockouts= 0 | rss= 40.1 MB | tick_mean= 3021.4 µs | ingest= 735.8 sim= 156.7 export= 110.8 diag= 0.1 µs | exported=914.34 MB acks=11257500
|
||||
tick= 3000 | entities= 75000 (sensor_active= 33889, alerts= 159, act= 7500) | faults=2042643 lockouts= 0 | rss= 51.5 MB | tick_mean= 3024.8 µs | ingest= 736.4 sim= 156.9 export= 110.8 diag= 0.1 µs | exported=1523.51 MB acks=18757500
|
||||
tick= 4000 | entities= 75000 (sensor_active= 33657, alerts= 166, act= 7500) | faults=2717674 lockouts= 0 | rss= 63.0 MB | tick_mean= 3022.6 µs | ingest= 735.3 sim= 156.9 export= 110.8 diag= 0.2 µs | exported=2132.66 MB acks=26257500
|
||||
tick= 5000 | entities= 75000 (sensor_active= 33573, alerts= 155, act= 7500) | faults=3393495 lockouts= 0 | rss= 74.4 MB | tick_mean= 3021.8 µs | ingest= 735.2 sim= 156.5 export= 110.8 diag= 0.2 µs | exported=2741.79 MB acks=33757500
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 15.118 s
|
||||
Sustained tick rate: 330.7 Hz
|
||||
Per-tick mean (wall): 302.3 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 736.2
|
||||
SimulationSystem: 156.6
|
||||
ExportSystem: 110.7
|
||||
DiagnosticsSystem: 0.3
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 3730093
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 3045.74 MB
|
||||
Acks processed: 37500000
|
||||
Alerts seen: 773395
|
||||
|
||||
Memory (RSS at end): 80.1 MB
|
||||
────────────────────────────────────────────────────────
|
||||
8
results_rpi/final_table.csv
Normal file
8
results_rpi/final_table.csv
Normal file
@@ -0,0 +1,8 @@
|
||||
entities,ticks,wall_s,hz,per_tick_us,ingest_us,sim_us,export_us,diag_us,sensor_faults,actuator_lockouts,exported_mb,acks,alerts,rss_mb
|
||||
10000,5000,,,,97.2,17.2,14.0,0.1,498016,0,,5000000,104943,
|
||||
25000,5000,,,,244.0,43.2,35.1,0.2,1243639,0,,12500000,254654,
|
||||
50000,5000,,,,496.0,94.5,70.8,0.2,2486121,0,,25000000,511654,
|
||||
75000,5000,,,,736.2,156.6,110.7,0.3,3730093,0,,37500000,773395,
|
||||
100000,5000,,,,985.7,217.2,150.1,0.2,4974449,0,,50000000,1029861,
|
||||
150000,5000,,,,1517.3,381.4,226.6,0.2,7460636,0,,75000000,1538845,
|
||||
200000,5000,,,,2022.7,582.0,300.7,0.2,9946420,0,,100000000,2059136,
|
||||
|
35
results_rpi/raw_10000.txt
Normal file
35
results_rpi/raw_10000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=10000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=7000 EventAsset=2000 ActuatorAsset=1000 total=10000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 10000 (sensor_active= 8817, alerts= 0, act= 1000) | faults= 183 lockouts= 0 | rss= 4.0 MB | tick_mean= 0.0 µs | ingest= 97.0 sim= 27.0 export= 14.0 diag= 0.0 µs | exported=0.08 MB acks=1000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 10000 (sensor_active= 4488, alerts= 23, act= 1000) | faults= 92482 lockouts= 0 | rss= 6.3 MB | tick_mean= 284.8 µs | ingest= 97.1 sim= 17.1 export= 14.0 diag= 0.0 µs | exported=40.70 MB acks=501000
|
||||
tick= 2000 | entities= 10000 (sensor_active= 4425, alerts= 23, act= 1000) | faults=182979 lockouts= 0 | rss= 7.8 MB | tick_mean= 286.0 µs | ingest= 97.1 sim= 17.2 export= 14.1 diag= 0.1 µs | exported=121.92 MB acks=1501000
|
||||
tick= 3000 | entities= 10000 (sensor_active= 4507, alerts= 27, act= 1000) | faults=273085 lockouts= 0 | rss= 9.3 MB | tick_mean= 286.1 µs | ingest= 97.3 sim= 17.3 export= 14.1 diag= 0.1 µs | exported=203.15 MB acks=2501000
|
||||
tick= 4000 | entities= 10000 (sensor_active= 4502, alerts= 15, act= 1000) | faults=363376 lockouts= 0 | rss= 10.9 MB | tick_mean= 284.8 µs | ingest= 97.0 sim= 17.2 export= 14.0 diag= 0.1 µs | exported=284.37 MB acks=3501000
|
||||
tick= 5000 | entities= 10000 (sensor_active= 4527, alerts= 24, act= 1000) | faults=453183 lockouts= 0 | rss= 12.4 MB | tick_mean= 284.6 µs | ingest= 97.1 sim= 17.2 export= 14.0 diag= 0.1 µs | exported=365.59 MB acks=4501000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 1.430 s
|
||||
Sustained tick rate: 3497.7 Hz
|
||||
Per-tick mean (wall): 28.5 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 97.2
|
||||
SimulationSystem: 17.2
|
||||
ExportSystem: 14.0
|
||||
DiagnosticsSystem: 0.1
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 498016
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 406.11 MB
|
||||
Acks processed: 5000000
|
||||
Alerts seen: 104943
|
||||
|
||||
Memory (RSS at end): 13.1 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results_rpi/raw_100000.txt
Normal file
35
results_rpi/raw_100000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=100000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=70000 EventAsset=20000 ActuatorAsset=10000 total=100000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 100000 (sensor_active= 88228, alerts= 0, act=10000) | faults= 1772 lockouts= 0 | rss= 16.3 MB | tick_mean= 0.0 µs | ingest= 948.0 sim= 607.0 export= 157.0 diag= 0.0 µs | exported=0.81 MB acks=10000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 100000 (sensor_active= 45396, alerts= 218, act=10000) | faults=924085 lockouts= 0 | rss= 36.7 MB | tick_mean= 4126.0 µs | ingest= 986.9 sim= 218.2 export= 150.2 diag= 0.0 µs | exported=406.92 MB acks=5010000
|
||||
tick= 2000 | entities= 100000 (sensor_active= 44998, alerts= 212, act=10000) | faults=1823730 lockouts= 0 | rss= 51.9 MB | tick_mean= 4197.8 µs | ingest= 987.7 sim= 236.6 export= 152.8 diag= 0.1 µs | exported=1219.14 MB acks=15010000
|
||||
tick= 3000 | entities= 100000 (sensor_active= 45132, alerts= 187, act=10000) | faults=2723608 lockouts= 0 | rss= 67.2 MB | tick_mean= 4132.4 µs | ingest= 986.1 sim= 217.8 export= 150.1 diag= 0.1 µs | exported=2031.31 MB acks=25010000
|
||||
tick= 4000 | entities= 100000 (sensor_active= 45039, alerts= 209, act=10000) | faults=3624295 lockouts= 0 | rss= 82.4 MB | tick_mean= 4132.1 µs | ingest= 986.5 sim= 217.8 export= 150.1 diag= 0.1 µs | exported=2843.48 MB acks=35010000
|
||||
tick= 5000 | entities= 100000 (sensor_active= 45069, alerts= 187, act=10000) | faults=4525217 lockouts= 0 | rss= 97.7 MB | tick_mean= 4132.9 µs | ingest= 985.3 sim= 217.1 export= 150.0 diag= 0.1 µs | exported=3655.69 MB acks=45010000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 20.732 s
|
||||
Sustained tick rate: 241.2 Hz
|
||||
Per-tick mean (wall): 413.0 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 985.7
|
||||
SimulationSystem: 217.2
|
||||
ExportSystem: 150.1
|
||||
DiagnosticsSystem: 0.2
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 4974449
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 4060.97 MB
|
||||
Acks processed: 50000000
|
||||
Alerts seen: 1029861
|
||||
|
||||
Memory (RSS at end): 105.3 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results_rpi/raw_150000.txt
Normal file
35
results_rpi/raw_150000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=150000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=105000 EventAsset=30000 ActuatorAsset=15000 total=150000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 150000 (sensor_active=132379, alerts= 0, act=15000) | faults= 2621 lockouts= 0 | rss= 24.5 MB | tick_mean= 0.0 µs | ingest=1444.0 sim= 884.0 export= 251.0 diag= 0.0 µs | exported=1.22 MB acks=15000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 150000 (sensor_active= 67721, alerts= 306, act=15000) | faults=1385323 lockouts= 0 | rss= 54.3 MB | tick_mean= 6453.6 µs | ingest=1517.1 sim= 381.6 export= 226.7 diag= 0.0 µs | exported=610.34 MB acks=7515000
|
||||
tick= 2000 | entities= 150000 (sensor_active= 67238, alerts= 279, act=15000) | faults=2736064 lockouts= 0 | rss= 77.2 MB | tick_mean= 6469.3 µs | ingest=1517.2 sim= 381.6 export= 226.8 diag= 0.1 µs | exported=1828.57 MB acks=22515000
|
||||
tick= 3000 | entities= 150000 (sensor_active= 67728, alerts= 317, act=15000) | faults=4087020 lockouts= 0 | rss= 100.1 MB | tick_mean= 6473.9 µs | ingest=1519.6 sim= 382.4 export= 227.0 diag= 0.1 µs | exported=3046.87 MB acks=37515000
|
||||
tick= 4000 | entities= 150000 (sensor_active= 67533, alerts= 320, act=15000) | faults=5437256 lockouts= 0 | rss= 123.0 MB | tick_mean= 6470.4 µs | ingest=1518.3 sim= 381.8 export= 226.7 diag= 0.1 µs | exported=4265.17 MB acks=52515000
|
||||
tick= 5000 | entities= 150000 (sensor_active= 67700, alerts= 323, act=15000) | faults=6786973 lockouts= 0 | rss= 145.8 MB | tick_mean= 6470.2 µs | ingest=1518.6 sim= 382.0 export= 226.7 diag= 0.1 µs | exported=5483.48 MB acks=67515000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 32.355 s
|
||||
Sustained tick rate: 154.5 Hz
|
||||
Per-tick mean (wall): 646.7 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 1517.3
|
||||
SimulationSystem: 381.4
|
||||
ExportSystem: 226.6
|
||||
DiagnosticsSystem: 0.2
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 7460636
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 6091.41 MB
|
||||
Acks processed: 75000000
|
||||
Alerts seen: 1538845
|
||||
|
||||
Memory (RSS at end): 157.2 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results_rpi/raw_200000.txt
Normal file
35
results_rpi/raw_200000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=200000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=140000 EventAsset=40000 ActuatorAsset=20000 total=200000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 200000 (sensor_active=176493, alerts= 0, act=20000) | faults= 3507 lockouts= 0 | rss= 30.0 MB | tick_mean= 0.0 µs | ingest=1907.0 sim=1336.0 export= 349.0 diag= 0.0 µs | exported=1.62 MB acks=20000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 200000 (sensor_active= 90145, alerts= 405, act=20000) | faults=1847083 lockouts= 0 | rss= 69.5 MB | tick_mean= 8788.2 µs | ingest=2023.3 sim= 582.9 export= 300.9 diag= 0.0 µs | exported=813.81 MB acks=10020000
|
||||
tick= 2000 | entities= 200000 (sensor_active= 90392, alerts= 396, act=20000) | faults=3647521 lockouts= 0 | rss= 100.0 MB | tick_mean= 8805.3 µs | ingest=2023.3 sim= 582.9 export= 300.5 diag= 0.1 µs | exported=2438.20 MB acks=30020000
|
||||
tick= 3000 | entities= 200000 (sensor_active= 90372, alerts= 408, act=20000) | faults=5447700 lockouts= 0 | rss= 130.5 MB | tick_mean= 8805.5 µs | ingest=2023.7 sim= 582.7 export= 300.4 diag= 0.1 µs | exported=4062.57 MB acks=50020000
|
||||
tick= 4000 | entities= 200000 (sensor_active= 89452, alerts= 444, act=20000) | faults=7247668 lockouts= 0 | rss= 161.1 MB | tick_mean= 8808.2 µs | ingest=2024.8 sim= 583.4 export= 300.7 diag= 0.2 µs | exported=5686.94 MB acks=70020000
|
||||
tick= 5000 | entities= 200000 (sensor_active= 89914, alerts= 429, act=20000) | faults=9047286 lockouts= 0 | rss= 191.6 MB | tick_mean= 8804.6 µs | ingest=2022.3 sim= 582.4 export= 300.7 diag= 0.1 µs | exported=7311.36 MB acks=90020000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 44.034 s
|
||||
Sustained tick rate: 113.5 Hz
|
||||
Per-tick mean (wall): 880.6 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 2022.7
|
||||
SimulationSystem: 582.0
|
||||
ExportSystem: 300.7
|
||||
DiagnosticsSystem: 0.2
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 9946420
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 8121.94 MB
|
||||
Acks processed: 100000000
|
||||
Alerts seen: 2059136
|
||||
|
||||
Memory (RSS at end): 206.8 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results_rpi/raw_25000.txt
Normal file
35
results_rpi/raw_25000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=25000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=17500 EventAsset=5000 ActuatorAsset=2500 total=25000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 25000 (sensor_active= 22049, alerts= 0, act= 2500) | faults= 451 lockouts= 0 | rss= 6.0 MB | tick_mean= 0.0 µs | ingest= 236.0 sim= 81.0 export= 36.0 diag= 0.0 µs | exported=0.20 MB acks=2500
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 25000 (sensor_active= 11440, alerts= 49, act= 2500) | faults=231419 lockouts= 0 | rss= 11.6 MB | tick_mean= 812.9 µs | ingest= 243.3 sim= 43.2 export= 35.1 diag= 0.0 µs | exported=101.74 MB acks=1252500
|
||||
tick= 2000 | entities= 25000 (sensor_active= 11301, alerts= 43, act= 2500) | faults=456552 lockouts= 0 | rss= 15.5 MB | tick_mean= 812.1 µs | ingest= 244.1 sim= 43.2 export= 35.1 diag= 0.1 µs | exported=304.78 MB acks=3752500
|
||||
tick= 3000 | entities= 25000 (sensor_active= 11421, alerts= 58, act= 2500) | faults=681247 lockouts= 0 | rss= 19.2 MB | tick_mean= 811.6 µs | ingest= 243.6 sim= 43.0 export= 35.1 diag= 0.1 µs | exported=507.82 MB acks=6252500
|
||||
tick= 4000 | entities= 25000 (sensor_active= 11157, alerts= 48, act= 2500) | faults=906865 lockouts= 0 | rss= 23.1 MB | tick_mean= 814.2 µs | ingest= 244.0 sim= 43.3 export= 35.1 diag= 0.1 µs | exported=710.88 MB acks=8752500
|
||||
tick= 5000 | entities= 25000 (sensor_active= 11216, alerts= 49, act= 2500) | faults=1131163 lockouts= 0 | rss= 26.9 MB | tick_mean= 811.4 µs | ingest= 243.6 sim= 43.2 export= 35.1 diag= 0.1 µs | exported=913.91 MB acks=11252500
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 4.066 s
|
||||
Sustained tick rate: 1229.7 Hz
|
||||
Per-tick mean (wall): 81.3 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 244.0
|
||||
SimulationSystem: 43.2
|
||||
ExportSystem: 35.1
|
||||
DiagnosticsSystem: 0.2
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 1243639
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 1015.22 MB
|
||||
Acks processed: 12500000
|
||||
Alerts seen: 254654
|
||||
|
||||
Memory (RSS at end): 28.8 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results_rpi/raw_50000.txt
Normal file
35
results_rpi/raw_50000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=50000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=35000 EventAsset=10000 ActuatorAsset=5000 total=50000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 50000 (sensor_active= 44082, alerts= 0, act= 5000) | faults= 918 lockouts= 0 | rss= 9.4 MB | tick_mean= 0.0 µs | ingest= 528.0 sim= 211.0 export= 73.0 diag= 0.0 µs | exported=0.41 MB acks=5000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 50000 (sensor_active= 22364, alerts= 118, act= 5000) | faults=462345 lockouts= 0 | rss= 20.1 MB | tick_mean= 1918.9 µs | ingest= 497.0 sim= 94.6 export= 70.9 diag= 0.0 µs | exported=203.46 MB acks=2505000
|
||||
tick= 2000 | entities= 50000 (sensor_active= 22510, alerts= 97, act= 5000) | faults=912440 lockouts= 0 | rss= 27.7 MB | tick_mean= 1922.8 µs | ingest= 496.6 sim= 94.4 export= 71.0 diag= 0.1 µs | exported=609.56 MB acks=7505000
|
||||
tick= 3000 | entities= 50000 (sensor_active= 22512, alerts= 90, act= 5000) | faults=1361728 lockouts= 0 | rss= 35.3 MB | tick_mean= 1924.0 µs | ingest= 497.0 sim= 94.7 export= 71.0 diag= 0.1 µs | exported=1015.66 MB acks=12505000
|
||||
tick= 4000 | entities= 50000 (sensor_active= 22519, alerts= 98, act= 5000) | faults=1812084 lockouts= 0 | rss= 43.0 MB | tick_mean= 1922.6 µs | ingest= 496.6 sim= 94.5 export= 70.8 diag= 0.1 µs | exported=1421.74 MB acks=17505000
|
||||
tick= 5000 | entities= 50000 (sensor_active= 22355, alerts= 101, act= 5000) | faults=2261407 lockouts= 0 | rss= 50.6 MB | tick_mean= 1921.7 µs | ingest= 496.7 sim= 94.5 export= 70.9 diag= 0.1 µs | exported=1827.82 MB acks=22505000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 9.617 s
|
||||
Sustained tick rate: 519.9 Hz
|
||||
Per-tick mean (wall): 192.0 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 496.0
|
||||
SimulationSystem: 94.5
|
||||
ExportSystem: 70.8
|
||||
DiagnosticsSystem: 0.2
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 2486121
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 2030.46 MB
|
||||
Acks processed: 25000000
|
||||
Alerts seen: 511654
|
||||
|
||||
Memory (RSS at end): 54.3 MB
|
||||
────────────────────────────────────────────────────────
|
||||
35
results_rpi/raw_75000.txt
Normal file
35
results_rpi/raw_75000.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=75000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=52500 EventAsset=15000 ActuatorAsset=7500 total=75000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 75000 (sensor_active= 66146, alerts= 0, act= 7500) | faults= 1354 lockouts= 0 | rss= 13.6 MB | tick_mean= 0.0 µs | ingest= 713.0 sim= 383.0 export= 112.0 diag= 0.0 µs | exported=0.61 MB acks=7500
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 75000 (sensor_active= 33877, alerts= 142, act= 7500) | faults=693165 lockouts= 0 | rss= 28.7 MB | tick_mean= 3016.1 µs | ingest= 735.8 sim= 156.6 export= 110.8 diag= 0.0 µs | exported=305.18 MB acks=3757500
|
||||
tick= 2000 | entities= 75000 (sensor_active= 33696, alerts= 166, act= 7500) | faults=1367793 lockouts= 0 | rss= 40.1 MB | tick_mean= 3021.4 µs | ingest= 735.8 sim= 156.7 export= 110.8 diag= 0.1 µs | exported=914.34 MB acks=11257500
|
||||
tick= 3000 | entities= 75000 (sensor_active= 33889, alerts= 159, act= 7500) | faults=2042643 lockouts= 0 | rss= 51.5 MB | tick_mean= 3024.8 µs | ingest= 736.4 sim= 156.9 export= 110.8 diag= 0.1 µs | exported=1523.51 MB acks=18757500
|
||||
tick= 4000 | entities= 75000 (sensor_active= 33657, alerts= 166, act= 7500) | faults=2717674 lockouts= 0 | rss= 63.0 MB | tick_mean= 3022.6 µs | ingest= 735.3 sim= 156.9 export= 110.8 diag= 0.2 µs | exported=2132.66 MB acks=26257500
|
||||
tick= 5000 | entities= 75000 (sensor_active= 33573, alerts= 155, act= 7500) | faults=3393495 lockouts= 0 | rss= 74.4 MB | tick_mean= 3021.8 µs | ingest= 735.2 sim= 156.5 export= 110.8 diag= 0.2 µs | exported=2741.79 MB acks=33757500
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 15.118 s
|
||||
Sustained tick rate: 330.7 Hz
|
||||
Per-tick mean (wall): 302.3 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 736.2
|
||||
SimulationSystem: 156.6
|
||||
ExportSystem: 110.7
|
||||
DiagnosticsSystem: 0.3
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 3730093
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 3045.74 MB
|
||||
Acks processed: 37500000
|
||||
Alerts seen: 773395
|
||||
|
||||
Memory (RSS at end): 80.1 MB
|
||||
────────────────────────────────────────────────────────
|
||||
283
results_rpi/summary.txt
Normal file
283
results_rpi/summary.txt
Normal file
@@ -0,0 +1,283 @@
|
||||
ECS DT Benchmark Sweep — Tue 21 Apr 01:12:15 UTC 2026
|
||||
=== System Information ===
|
||||
Date: 2026-04-21 01:12:15 UTC
|
||||
OS: Linux 6.12.75+rpt-rpi-2712
|
||||
Arch: aarch64
|
||||
Target CPU: cortex-a76
|
||||
Rust: rustc 1.95.0 (59807616e 2026-04-14)
|
||||
Cargo: cargo 1.95.0 (f2d3ce0bd 2026-03-21)
|
||||
|
||||
=== CPU Info ===
|
||||
CPU implementer : 0x41
|
||||
CPU part : 0xd0b
|
||||
Revision : c04180
|
||||
|
||||
=== Memory ===
|
||||
MemTotal: 4146896 kB
|
||||
MemAvailable: 3883072 kB
|
||||
|
||||
=== CPU Governor ===
|
||||
/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor: performance
|
||||
|
||||
=== Isolated cores ===
|
||||
|
||||
|
||||
|
||||
=== entities=10000 ===
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=10000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=7000 EventAsset=2000 ActuatorAsset=1000 total=10000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 10000 (sensor_active= 8817, alerts= 0, act= 1000) | faults= 183 lockouts= 0 | rss= 4.0 MB | tick_mean= 0.0 µs | ingest= 97.0 sim= 27.0 export= 14.0 diag= 0.0 µs | exported=0.08 MB acks=1000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 10000 (sensor_active= 4488, alerts= 23, act= 1000) | faults= 92482 lockouts= 0 | rss= 6.3 MB | tick_mean= 284.8 µs | ingest= 97.1 sim= 17.1 export= 14.0 diag= 0.0 µs | exported=40.70 MB acks=501000
|
||||
tick= 2000 | entities= 10000 (sensor_active= 4425, alerts= 23, act= 1000) | faults=182979 lockouts= 0 | rss= 7.8 MB | tick_mean= 286.0 µs | ingest= 97.1 sim= 17.2 export= 14.1 diag= 0.1 µs | exported=121.92 MB acks=1501000
|
||||
tick= 3000 | entities= 10000 (sensor_active= 4507, alerts= 27, act= 1000) | faults=273085 lockouts= 0 | rss= 9.3 MB | tick_mean= 286.1 µs | ingest= 97.3 sim= 17.3 export= 14.1 diag= 0.1 µs | exported=203.15 MB acks=2501000
|
||||
tick= 4000 | entities= 10000 (sensor_active= 4502, alerts= 15, act= 1000) | faults=363376 lockouts= 0 | rss= 10.9 MB | tick_mean= 284.8 µs | ingest= 97.0 sim= 17.2 export= 14.0 diag= 0.1 µs | exported=284.37 MB acks=3501000
|
||||
tick= 5000 | entities= 10000 (sensor_active= 4527, alerts= 24, act= 1000) | faults=453183 lockouts= 0 | rss= 12.4 MB | tick_mean= 284.6 µs | ingest= 97.1 sim= 17.2 export= 14.0 diag= 0.1 µs | exported=365.59 MB acks=4501000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 1.430 s
|
||||
Sustained tick rate: 3497.7 Hz
|
||||
Per-tick mean (wall): 28.5 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 97.2
|
||||
SimulationSystem: 17.2
|
||||
ExportSystem: 14.0
|
||||
DiagnosticsSystem: 0.1
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 498016
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 406.11 MB
|
||||
Acks processed: 5000000
|
||||
Alerts seen: 104943
|
||||
|
||||
Memory (RSS at end): 13.1 MB
|
||||
────────────────────────────────────────────────────────
|
||||
|
||||
=== entities=25000 ===
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=25000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=17500 EventAsset=5000 ActuatorAsset=2500 total=25000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 25000 (sensor_active= 22049, alerts= 0, act= 2500) | faults= 451 lockouts= 0 | rss= 6.0 MB | tick_mean= 0.0 µs | ingest= 236.0 sim= 81.0 export= 36.0 diag= 0.0 µs | exported=0.20 MB acks=2500
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 25000 (sensor_active= 11440, alerts= 49, act= 2500) | faults=231419 lockouts= 0 | rss= 11.6 MB | tick_mean= 812.9 µs | ingest= 243.3 sim= 43.2 export= 35.1 diag= 0.0 µs | exported=101.74 MB acks=1252500
|
||||
tick= 2000 | entities= 25000 (sensor_active= 11301, alerts= 43, act= 2500) | faults=456552 lockouts= 0 | rss= 15.5 MB | tick_mean= 812.1 µs | ingest= 244.1 sim= 43.2 export= 35.1 diag= 0.1 µs | exported=304.78 MB acks=3752500
|
||||
tick= 3000 | entities= 25000 (sensor_active= 11421, alerts= 58, act= 2500) | faults=681247 lockouts= 0 | rss= 19.2 MB | tick_mean= 811.6 µs | ingest= 243.6 sim= 43.0 export= 35.1 diag= 0.1 µs | exported=507.82 MB acks=6252500
|
||||
tick= 4000 | entities= 25000 (sensor_active= 11157, alerts= 48, act= 2500) | faults=906865 lockouts= 0 | rss= 23.1 MB | tick_mean= 814.2 µs | ingest= 244.0 sim= 43.3 export= 35.1 diag= 0.1 µs | exported=710.88 MB acks=8752500
|
||||
tick= 5000 | entities= 25000 (sensor_active= 11216, alerts= 49, act= 2500) | faults=1131163 lockouts= 0 | rss= 26.9 MB | tick_mean= 811.4 µs | ingest= 243.6 sim= 43.2 export= 35.1 diag= 0.1 µs | exported=913.91 MB acks=11252500
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 4.066 s
|
||||
Sustained tick rate: 1229.7 Hz
|
||||
Per-tick mean (wall): 81.3 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 244.0
|
||||
SimulationSystem: 43.2
|
||||
ExportSystem: 35.1
|
||||
DiagnosticsSystem: 0.2
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 1243639
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 1015.22 MB
|
||||
Acks processed: 12500000
|
||||
Alerts seen: 254654
|
||||
|
||||
Memory (RSS at end): 28.8 MB
|
||||
────────────────────────────────────────────────────────
|
||||
|
||||
=== entities=50000 ===
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=50000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=35000 EventAsset=10000 ActuatorAsset=5000 total=50000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 50000 (sensor_active= 44082, alerts= 0, act= 5000) | faults= 918 lockouts= 0 | rss= 9.4 MB | tick_mean= 0.0 µs | ingest= 528.0 sim= 211.0 export= 73.0 diag= 0.0 µs | exported=0.41 MB acks=5000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 50000 (sensor_active= 22364, alerts= 118, act= 5000) | faults=462345 lockouts= 0 | rss= 20.1 MB | tick_mean= 1918.9 µs | ingest= 497.0 sim= 94.6 export= 70.9 diag= 0.0 µs | exported=203.46 MB acks=2505000
|
||||
tick= 2000 | entities= 50000 (sensor_active= 22510, alerts= 97, act= 5000) | faults=912440 lockouts= 0 | rss= 27.7 MB | tick_mean= 1922.8 µs | ingest= 496.6 sim= 94.4 export= 71.0 diag= 0.1 µs | exported=609.56 MB acks=7505000
|
||||
tick= 3000 | entities= 50000 (sensor_active= 22512, alerts= 90, act= 5000) | faults=1361728 lockouts= 0 | rss= 35.3 MB | tick_mean= 1924.0 µs | ingest= 497.0 sim= 94.7 export= 71.0 diag= 0.1 µs | exported=1015.66 MB acks=12505000
|
||||
tick= 4000 | entities= 50000 (sensor_active= 22519, alerts= 98, act= 5000) | faults=1812084 lockouts= 0 | rss= 43.0 MB | tick_mean= 1922.6 µs | ingest= 496.6 sim= 94.5 export= 70.8 diag= 0.1 µs | exported=1421.74 MB acks=17505000
|
||||
tick= 5000 | entities= 50000 (sensor_active= 22355, alerts= 101, act= 5000) | faults=2261407 lockouts= 0 | rss= 50.6 MB | tick_mean= 1921.7 µs | ingest= 496.7 sim= 94.5 export= 70.9 diag= 0.1 µs | exported=1827.82 MB acks=22505000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 9.617 s
|
||||
Sustained tick rate: 519.9 Hz
|
||||
Per-tick mean (wall): 192.0 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 496.0
|
||||
SimulationSystem: 94.5
|
||||
ExportSystem: 70.8
|
||||
DiagnosticsSystem: 0.2
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 2486121
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 2030.46 MB
|
||||
Acks processed: 25000000
|
||||
Alerts seen: 511654
|
||||
|
||||
Memory (RSS at end): 54.3 MB
|
||||
────────────────────────────────────────────────────────
|
||||
|
||||
=== entities=75000 ===
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=75000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=52500 EventAsset=15000 ActuatorAsset=7500 total=75000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 75000 (sensor_active= 66146, alerts= 0, act= 7500) | faults= 1354 lockouts= 0 | rss= 13.6 MB | tick_mean= 0.0 µs | ingest= 713.0 sim= 383.0 export= 112.0 diag= 0.0 µs | exported=0.61 MB acks=7500
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 75000 (sensor_active= 33877, alerts= 142, act= 7500) | faults=693165 lockouts= 0 | rss= 28.7 MB | tick_mean= 3016.1 µs | ingest= 735.8 sim= 156.6 export= 110.8 diag= 0.0 µs | exported=305.18 MB acks=3757500
|
||||
tick= 2000 | entities= 75000 (sensor_active= 33696, alerts= 166, act= 7500) | faults=1367793 lockouts= 0 | rss= 40.1 MB | tick_mean= 3021.4 µs | ingest= 735.8 sim= 156.7 export= 110.8 diag= 0.1 µs | exported=914.34 MB acks=11257500
|
||||
tick= 3000 | entities= 75000 (sensor_active= 33889, alerts= 159, act= 7500) | faults=2042643 lockouts= 0 | rss= 51.5 MB | tick_mean= 3024.8 µs | ingest= 736.4 sim= 156.9 export= 110.8 diag= 0.1 µs | exported=1523.51 MB acks=18757500
|
||||
tick= 4000 | entities= 75000 (sensor_active= 33657, alerts= 166, act= 7500) | faults=2717674 lockouts= 0 | rss= 63.0 MB | tick_mean= 3022.6 µs | ingest= 735.3 sim= 156.9 export= 110.8 diag= 0.2 µs | exported=2132.66 MB acks=26257500
|
||||
tick= 5000 | entities= 75000 (sensor_active= 33573, alerts= 155, act= 7500) | faults=3393495 lockouts= 0 | rss= 74.4 MB | tick_mean= 3021.8 µs | ingest= 735.2 sim= 156.5 export= 110.8 diag= 0.2 µs | exported=2741.79 MB acks=33757500
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 15.118 s
|
||||
Sustained tick rate: 330.7 Hz
|
||||
Per-tick mean (wall): 302.3 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 736.2
|
||||
SimulationSystem: 156.6
|
||||
ExportSystem: 110.7
|
||||
DiagnosticsSystem: 0.3
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 3730093
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 3045.74 MB
|
||||
Acks processed: 37500000
|
||||
Alerts seen: 773395
|
||||
|
||||
Memory (RSS at end): 80.1 MB
|
||||
────────────────────────────────────────────────────────
|
||||
|
||||
=== entities=100000 ===
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=100000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=70000 EventAsset=20000 ActuatorAsset=10000 total=100000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 100000 (sensor_active= 88228, alerts= 0, act=10000) | faults= 1772 lockouts= 0 | rss= 16.3 MB | tick_mean= 0.0 µs | ingest= 948.0 sim= 607.0 export= 157.0 diag= 0.0 µs | exported=0.81 MB acks=10000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 100000 (sensor_active= 45396, alerts= 218, act=10000) | faults=924085 lockouts= 0 | rss= 36.7 MB | tick_mean= 4126.0 µs | ingest= 986.9 sim= 218.2 export= 150.2 diag= 0.0 µs | exported=406.92 MB acks=5010000
|
||||
tick= 2000 | entities= 100000 (sensor_active= 44998, alerts= 212, act=10000) | faults=1823730 lockouts= 0 | rss= 51.9 MB | tick_mean= 4197.8 µs | ingest= 987.7 sim= 236.6 export= 152.8 diag= 0.1 µs | exported=1219.14 MB acks=15010000
|
||||
tick= 3000 | entities= 100000 (sensor_active= 45132, alerts= 187, act=10000) | faults=2723608 lockouts= 0 | rss= 67.2 MB | tick_mean= 4132.4 µs | ingest= 986.1 sim= 217.8 export= 150.1 diag= 0.1 µs | exported=2031.31 MB acks=25010000
|
||||
tick= 4000 | entities= 100000 (sensor_active= 45039, alerts= 209, act=10000) | faults=3624295 lockouts= 0 | rss= 82.4 MB | tick_mean= 4132.1 µs | ingest= 986.5 sim= 217.8 export= 150.1 diag= 0.1 µs | exported=2843.48 MB acks=35010000
|
||||
tick= 5000 | entities= 100000 (sensor_active= 45069, alerts= 187, act=10000) | faults=4525217 lockouts= 0 | rss= 97.7 MB | tick_mean= 4132.9 µs | ingest= 985.3 sim= 217.1 export= 150.0 diag= 0.1 µs | exported=3655.69 MB acks=45010000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 20.732 s
|
||||
Sustained tick rate: 241.2 Hz
|
||||
Per-tick mean (wall): 413.0 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 985.7
|
||||
SimulationSystem: 217.2
|
||||
ExportSystem: 150.1
|
||||
DiagnosticsSystem: 0.2
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 4974449
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 4060.97 MB
|
||||
Acks processed: 50000000
|
||||
Alerts seen: 1029861
|
||||
|
||||
Memory (RSS at end): 105.3 MB
|
||||
────────────────────────────────────────────────────────
|
||||
|
||||
=== entities=150000 ===
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=150000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=105000 EventAsset=30000 ActuatorAsset=15000 total=150000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 150000 (sensor_active=132379, alerts= 0, act=15000) | faults= 2621 lockouts= 0 | rss= 24.5 MB | tick_mean= 0.0 µs | ingest=1444.0 sim= 884.0 export= 251.0 diag= 0.0 µs | exported=1.22 MB acks=15000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 150000 (sensor_active= 67721, alerts= 306, act=15000) | faults=1385323 lockouts= 0 | rss= 54.3 MB | tick_mean= 6453.6 µs | ingest=1517.1 sim= 381.6 export= 226.7 diag= 0.0 µs | exported=610.34 MB acks=7515000
|
||||
tick= 2000 | entities= 150000 (sensor_active= 67238, alerts= 279, act=15000) | faults=2736064 lockouts= 0 | rss= 77.2 MB | tick_mean= 6469.3 µs | ingest=1517.2 sim= 381.6 export= 226.8 diag= 0.1 µs | exported=1828.57 MB acks=22515000
|
||||
tick= 3000 | entities= 150000 (sensor_active= 67728, alerts= 317, act=15000) | faults=4087020 lockouts= 0 | rss= 100.1 MB | tick_mean= 6473.9 µs | ingest=1519.6 sim= 382.4 export= 227.0 diag= 0.1 µs | exported=3046.87 MB acks=37515000
|
||||
tick= 4000 | entities= 150000 (sensor_active= 67533, alerts= 320, act=15000) | faults=5437256 lockouts= 0 | rss= 123.0 MB | tick_mean= 6470.4 µs | ingest=1518.3 sim= 381.8 export= 226.7 diag= 0.1 µs | exported=4265.17 MB acks=52515000
|
||||
tick= 5000 | entities= 150000 (sensor_active= 67700, alerts= 323, act=15000) | faults=6786973 lockouts= 0 | rss= 145.8 MB | tick_mean= 6470.2 µs | ingest=1518.6 sim= 382.0 export= 226.7 diag= 0.1 µs | exported=5483.48 MB acks=67515000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 32.355 s
|
||||
Sustained tick rate: 154.5 Hz
|
||||
Per-tick mean (wall): 646.7 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 1517.3
|
||||
SimulationSystem: 381.4
|
||||
ExportSystem: 226.6
|
||||
DiagnosticsSystem: 0.2
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 7460636
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 6091.41 MB
|
||||
Acks processed: 75000000
|
||||
Alerts seen: 1538845
|
||||
|
||||
Memory (RSS at end): 157.2 MB
|
||||
────────────────────────────────────────────────────────
|
||||
|
||||
=== entities=200000 ===
|
||||
ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
entities=200000 | ticks=5000 | warmup=500 | fault_prob=2.0%
|
||||
[spawn] SensorAsset=140000 EventAsset=40000 ActuatorAsset=20000 total=200000
|
||||
[warmup] running 500 ticks...
|
||||
tick= 0 | entities= 200000 (sensor_active=176493, alerts= 0, act=20000) | faults= 3507 lockouts= 0 | rss= 30.0 MB | tick_mean= 0.0 µs | ingest=1907.0 sim=1336.0 export= 349.0 diag= 0.0 µs | exported=1.62 MB acks=20000
|
||||
[warmup] done — starting measurement (5000 ticks)
|
||||
tick= 1000 | entities= 200000 (sensor_active= 90145, alerts= 405, act=20000) | faults=1847083 lockouts= 0 | rss= 69.5 MB | tick_mean= 8788.2 µs | ingest=2023.3 sim= 582.9 export= 300.9 diag= 0.0 µs | exported=813.81 MB acks=10020000
|
||||
tick= 2000 | entities= 200000 (sensor_active= 90392, alerts= 396, act=20000) | faults=3647521 lockouts= 0 | rss= 100.0 MB | tick_mean= 8805.3 µs | ingest=2023.3 sim= 582.9 export= 300.5 diag= 0.1 µs | exported=2438.20 MB acks=30020000
|
||||
tick= 3000 | entities= 200000 (sensor_active= 90372, alerts= 408, act=20000) | faults=5447700 lockouts= 0 | rss= 130.5 MB | tick_mean= 8805.5 µs | ingest=2023.7 sim= 582.7 export= 300.4 diag= 0.1 µs | exported=4062.57 MB acks=50020000
|
||||
tick= 4000 | entities= 200000 (sensor_active= 89452, alerts= 444, act=20000) | faults=7247668 lockouts= 0 | rss= 161.1 MB | tick_mean= 8808.2 µs | ingest=2024.8 sim= 583.4 export= 300.7 diag= 0.2 µs | exported=5686.94 MB acks=70020000
|
||||
tick= 5000 | entities= 200000 (sensor_active= 89914, alerts= 429, act=20000) | faults=9047286 lockouts= 0 | rss= 191.6 MB | tick_mean= 8804.6 µs | ingest=2022.3 sim= 582.4 export= 300.7 diag= 0.1 µs | exported=7311.36 MB acks=90020000
|
||||
|
||||
── Final Summary ──────────────────────────────────────
|
||||
Total ticks (measurement): 5000
|
||||
Total wall time: 44.034 s
|
||||
Sustained tick rate: 113.5 Hz
|
||||
Per-tick mean (wall): 880.6 µs
|
||||
|
||||
Per-system mean (µs):
|
||||
IngestSystem: 2022.7
|
||||
SimulationSystem: 582.0
|
||||
ExportSystem: 300.7
|
||||
DiagnosticsSystem: 0.2
|
||||
|
||||
Fault injection:
|
||||
Total sensor faults: 9946420
|
||||
Total actuator lockouts: 0
|
||||
|
||||
Export totals:
|
||||
Bytes exported: 8121.94 MB
|
||||
Acks processed: 100000000
|
||||
Alerts seen: 2059136
|
||||
|
||||
Memory (RSS at end): 206.8 MB
|
||||
────────────────────────────────────────────────────────
|
||||
22
results_rpi/sysinfo.txt
Normal file
22
results_rpi/sysinfo.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
=== System Information ===
|
||||
Date: 2026-04-21 01:12:15 UTC
|
||||
OS: Linux 6.12.75+rpt-rpi-2712
|
||||
Arch: aarch64
|
||||
Target CPU: cortex-a76
|
||||
Rust: rustc 1.95.0 (59807616e 2026-04-14)
|
||||
Cargo: cargo 1.95.0 (f2d3ce0bd 2026-03-21)
|
||||
|
||||
=== CPU Info ===
|
||||
CPU implementer : 0x41
|
||||
CPU part : 0xd0b
|
||||
Revision : c04180
|
||||
|
||||
=== Memory ===
|
||||
MemTotal: 4146896 kB
|
||||
MemAvailable: 3883072 kB
|
||||
|
||||
=== CPU Governor ===
|
||||
/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor: performance
|
||||
|
||||
=== Isolated cores ===
|
||||
|
||||
265
run_benchmark.sh
Executable file
265
run_benchmark.sh
Executable file
@@ -0,0 +1,265 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================
|
||||
# ECS Digital Twin Benchmark — build + full sweep
|
||||
# TRANSIT lab / UQAC
|
||||
#
|
||||
# Detects the host CPU, builds with native hardware optimizations,
|
||||
# then runs the full entity sweep for the paper tables.
|
||||
#
|
||||
# Usage:
|
||||
# chmod +x run_benchmark.sh
|
||||
# ./run_benchmark.sh
|
||||
#
|
||||
# Output:
|
||||
# results/summary.txt — human-readable full log
|
||||
# results/csv/ — one CSV per entity count (for paper tables)
|
||||
# results/final_table.csv — aggregated table ready for LaTeX
|
||||
# =============================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ── Paths ─────────────────────────────────────────────────────
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
RESULTS_DIR="${SCRIPT_DIR}/results"
|
||||
CSV_DIR="${RESULTS_DIR}/csv"
|
||||
BINARY="${SCRIPT_DIR}/target/release/ecs_dt_benchmark"
|
||||
|
||||
mkdir -p "${RESULTS_DIR}" "${CSV_DIR}"
|
||||
|
||||
# ── Benchmark parameters ───────────────────────────────────────
|
||||
ENTITY_COUNTS=(10000 25000 50000 75000 100000 150000 200000)
|
||||
TICKS=5000
|
||||
WARMUP=500
|
||||
FAULT_PROB=0.02 # 2 % per tick per entity
|
||||
SEED=17446744073709551615
|
||||
|
||||
# ── Platform detection ────────────────────────────────────────
|
||||
ARCH="$(uname -m)"
|
||||
OS="$(uname -s)"
|
||||
|
||||
echo "============================================================"
|
||||
echo " ECS Digital Twin Benchmark — TRANSIT lab / UQAC"
|
||||
echo " Platform: ${OS} / ${ARCH}"
|
||||
echo "============================================================"
|
||||
|
||||
# Detect the best target-cpu flag for this machine.
|
||||
detect_target_cpu() {
|
||||
case "${ARCH}" in
|
||||
aarch64)
|
||||
# On RPi 5 (Cortex-A76) /proc/cpuinfo lists "CPU part : 0xd0b"
|
||||
# On Apple M-series (native aarch64 via Rosetta or native build)
|
||||
# uname gives arm64 on macOS, aarch64 on Linux.
|
||||
if [[ "${OS}" == "Darwin" ]]; then
|
||||
# Apple Silicon — the toolchain knows the exact µarch.
|
||||
echo "apple-m1"
|
||||
elif grep -q "Cortex-A76" /proc/cpuinfo 2>/dev/null || \
|
||||
grep -q "0xd0b" /proc/cpuinfo 2>/dev/null; then
|
||||
echo "cortex-a76" # RPi 5
|
||||
elif grep -q "Cortex-A72" /proc/cpuinfo 2>/dev/null || \
|
||||
grep -q "0xd08" /proc/cpuinfo 2>/dev/null; then
|
||||
echo "cortex-a72" # RPi 4
|
||||
else
|
||||
echo "native" # fall back: let LLVM auto-detect
|
||||
fi
|
||||
;;
|
||||
x86_64)
|
||||
echo "native" # covers Ryzen, Intel, any x86-64
|
||||
;;
|
||||
arm64)
|
||||
# macOS reports arm64
|
||||
echo "apple-m1"
|
||||
;;
|
||||
*)
|
||||
echo "native"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
TARGET_CPU="$(detect_target_cpu)"
|
||||
echo " Target CPU flag: -C target-cpu=${TARGET_CPU}"
|
||||
|
||||
# ── CPU isolation advice ───────────────────────────────────────
|
||||
# On Linux, pin to an isolated core if isolcpus was set at boot.
|
||||
# On the RPi 5 for the paper we recommend:
|
||||
# sudo systemctl isolate multi-user.target (drop GUI)
|
||||
# TASKSET="taskset -c 0"
|
||||
# We auto-detect isolated cores from the kernel cmdline.
|
||||
TASKSET=""
|
||||
if [[ "${OS}" == "Linux" ]]; then
|
||||
ISOLATED=""
|
||||
if [[ -r /sys/devices/system/cpu/isolated ]]; then
|
||||
ISOLATED="$(cat /sys/devices/system/cpu/isolated)"
|
||||
fi
|
||||
if [[ -n "${ISOLATED}" ]]; then
|
||||
# Use the first isolated core.
|
||||
FIRST_CORE="${ISOLATED%%[-,]*}"
|
||||
TASKSET="taskset -c ${FIRST_CORE}"
|
||||
echo " Isolated cores: ${ISOLATED} → pinning to core ${FIRST_CORE}"
|
||||
else
|
||||
echo " No isolated cores detected — running unpinned."
|
||||
echo " Tip: add isolcpus=2 nohz_full=2 rcu_nocbs=2 to /boot/cmdline.txt"
|
||||
echo " for more stable single-core measurements on RPi 5."
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── Build ──────────────────────────────────────────────────────
|
||||
echo ""
|
||||
echo "── Building (release + native optimizations) ────────────"
|
||||
|
||||
RUSTFLAGS="-C target-cpu=${TARGET_CPU} -C opt-level=3" \
|
||||
cargo build --release 2>&1 | tail -5
|
||||
|
||||
echo " Binary: ${BINARY}"
|
||||
echo " Size: $(du -sh "${BINARY}" | cut -f1)"
|
||||
|
||||
# ── System info snapshot ───────────────────────────────────────
|
||||
SYSINFO_FILE="${RESULTS_DIR}/sysinfo.txt"
|
||||
{
|
||||
echo "=== System Information ==="
|
||||
echo "Date: $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
|
||||
echo "OS: ${OS} $(uname -r 2>/dev/null || true)"
|
||||
echo "Arch: ${ARCH}"
|
||||
echo "Target CPU: ${TARGET_CPU}"
|
||||
echo "Rust: $(rustc --version)"
|
||||
echo "Cargo: $(cargo --version)"
|
||||
echo ""
|
||||
if [[ "${OS}" == "Linux" ]]; then
|
||||
echo "=== CPU Info ==="
|
||||
grep -E "^(model name|Hardware|CPU part|CPU implementer|Revision)" \
|
||||
/proc/cpuinfo 2>/dev/null | sort -u || true
|
||||
echo ""
|
||||
echo "=== Memory ==="
|
||||
grep -E "^(MemTotal|MemAvailable)" /proc/meminfo 2>/dev/null || true
|
||||
echo ""
|
||||
echo "=== CPU Governor ==="
|
||||
for f in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
|
||||
[[ -r "$f" ]] && echo " $f: $(cat "$f")" && break
|
||||
done
|
||||
echo ""
|
||||
echo "=== Isolated cores ==="
|
||||
cat /sys/devices/system/cpu/isolated 2>/dev/null || echo " none"
|
||||
elif [[ "${OS}" == "Darwin" ]]; then
|
||||
sysctl -n machdep.cpu.brand_string 2>/dev/null || true
|
||||
sysctl -n hw.memsize 2>/dev/null | \
|
||||
awk '{printf "Memory: %.1f GB\n", $1/1073741824}' || true
|
||||
fi
|
||||
} | tee "${SYSINFO_FILE}"
|
||||
|
||||
echo ""
|
||||
|
||||
# ── CSV header ────────────────────────────────────────────────
|
||||
FINAL_CSV="${RESULTS_DIR}/final_table.csv"
|
||||
echo "entities,ticks,wall_s,hz,per_tick_us,ingest_us,sim_us,export_us,diag_us,\
|
||||
sensor_faults,actuator_lockouts,exported_mb,acks,alerts,rss_mb" \
|
||||
> "${FINAL_CSV}"
|
||||
|
||||
# ── Sweep ─────────────────────────────────────────────────────
|
||||
echo "── Running entity sweep ─────────────────────────────────"
|
||||
echo " Counts: ${ENTITY_COUNTS[*]}"
|
||||
echo " Ticks: ${TICKS} Warmup: ${WARMUP} Fault: ${FAULT_PROB}"
|
||||
echo ""
|
||||
|
||||
SUMMARY_FILE="${RESULTS_DIR}/summary.txt"
|
||||
echo "ECS DT Benchmark Sweep — $(date -u)" > "${SUMMARY_FILE}"
|
||||
cat "${SYSINFO_FILE}" >> "${SUMMARY_FILE}"
|
||||
echo "" >> "${SUMMARY_FILE}"
|
||||
|
||||
for N in "${ENTITY_COUNTS[@]}"; do
|
||||
echo "── entities=${N} ─────────────────────────────────────"
|
||||
|
||||
RAW_FILE="${RESULTS_DIR}/raw_${N}.txt"
|
||||
|
||||
# Run benchmark, tee to file and stdout.
|
||||
# shellcheck disable=SC2086
|
||||
${TASKSET} "${BINARY}" \
|
||||
--entities "${N}" \
|
||||
--ticks "${TICKS}" \
|
||||
--seed "${SEED}" \
|
||||
--fault-prob "${FAULT_PROB}" \
|
||||
2>&1 | tee "${RAW_FILE}"
|
||||
|
||||
echo "" >> "${SUMMARY_FILE}"
|
||||
echo "=== entities=${N} ===" >> "${SUMMARY_FILE}"
|
||||
cat "${RAW_FILE}" >> "${SUMMARY_FILE}"
|
||||
|
||||
# ── Parse the Final Summary block from the binary output ──
|
||||
# Extract values using grep + awk on the known output format.
|
||||
parse() {
|
||||
grep -m1 "$1" "${RAW_FILE}" | awk '{print $NF}'
|
||||
}
|
||||
|
||||
WALL_S=$(grep "Total wall time" "${RAW_FILE}" | awk '{print $NF}' | tr -d 's')
|
||||
HZ=$(grep "Sustained tick rate" "${RAW_FILE}" | awk '{print $NF}')
|
||||
PTW=$(grep "Per-tick mean" "${RAW_FILE}" | awk '{print $NF}')
|
||||
INGEST=$(grep "IngestSystem:" "${RAW_FILE}" | tail -1 | awk '{print $NF}')
|
||||
SIM=$(grep "SimulationSystem:" "${RAW_FILE}" | tail -1 | awk '{print $NF}')
|
||||
EXPORT=$(grep "ExportSystem:" "${RAW_FILE}" | tail -1 | awk '{print $NF}')
|
||||
DIAGSYS=$(grep "DiagnosticsSystem:" "${RAW_FILE}" | tail -1 | awk '{print $NF}')
|
||||
FAULTS=$(grep "Total sensor faults:" "${RAW_FILE}" | awk '{print $NF}')
|
||||
LOCKOUTS=$(grep "Total actuator lockouts" "${RAW_FILE}" | awk '{print $NF}')
|
||||
EXPMT=$(grep "Bytes exported:" "${RAW_FILE}" | awk '{print $NF}')
|
||||
ACKS=$(grep "Acks processed:" "${RAW_FILE}" | awk '{print $NF}')
|
||||
ALTS=$(grep "Alerts seen:" "${RAW_FILE}" | awk '{print $NF}')
|
||||
RSS=$(grep "Memory (RSS" "${RAW_FILE}" | awk '{print $NF}')
|
||||
|
||||
# Remove trailing units that awk picked up (MB, Hz, µs, s).
|
||||
strip() { echo "$1" | tr -d 'MBHzµs '; }
|
||||
|
||||
echo "${N},${TICKS},$(strip "$WALL_S"),$(strip "$HZ"),$(strip "$PTW"),\
|
||||
$(strip "$INGEST"),$(strip "$SIM"),$(strip "$EXPORT"),$(strip "$DIAGSYS"),\
|
||||
$(strip "$FAULTS"),$(strip "$LOCKOUTS"),$(strip "$EXPMT"),\
|
||||
$(strip "$ACKS"),$(strip "$ALTS"),$(strip "$RSS")" \
|
||||
>> "${FINAL_CSV}"
|
||||
|
||||
# Per-entity CSV for detailed analysis.
|
||||
cat "${RAW_FILE}" > "${CSV_DIR}/entities_${N}.txt"
|
||||
|
||||
echo ""
|
||||
done
|
||||
|
||||
# ── Pretty-print final table ──────────────────────────────────
|
||||
echo "============================================================"
|
||||
echo " Final Results Table"
|
||||
echo "============================================================"
|
||||
echo ""
|
||||
printf "%-10s %-8s %-10s %-12s %-12s %-10s %-10s\n" \
|
||||
"Entities" "Hz" "Tick(µs)" "Ingest(µs)" "Sim(µs)" "Export(µs)" "RSS(MB)"
|
||||
printf "%-10s %-8s %-10s %-12s %-12s %-10s %-10s\n" \
|
||||
"--------" "------" "---------" "----------" "--------" "----------" "-------"
|
||||
|
||||
tail -n +2 "${FINAL_CSV}" | while IFS=',' read -r \
|
||||
entities ticks wall hz ptw ingest sim export diag \
|
||||
faults lockouts expmt acks alts rss; do
|
||||
printf "%-10s %-8s %-10s %-12s %-12s %-10s %-10s\n" \
|
||||
"${entities}" "${hz}" "${ptw}" "${ingest}" "${sim}" "${export}" "${rss}"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "── Output files ─────────────────────────────────────────"
|
||||
echo " ${SUMMARY_FILE}"
|
||||
echo " ${FINAL_CSV}"
|
||||
echo " ${CSV_DIR}/"
|
||||
echo ""
|
||||
echo "── LaTeX snippet for paper Table 2 ─────────────────────"
|
||||
echo '\begin{table}[h]'
|
||||
echo '\caption{ECS DT Runtime: Memory and Throughput Scaling (RPi~5, single core)}'
|
||||
echo '\centering\renewcommand{\arraystretch}{1.25}'
|
||||
echo '\begin{tabular}{@{}rrrrr@{}}'
|
||||
echo '\toprule'
|
||||
echo '\textbf{Entities} & \textbf{RSS (MB)} & \textbf{Tick rate (Hz)} &'
|
||||
echo '\textbf{Per-tick ($\mu$s)} & \textbf{Sim system ($\mu$s)} \\'
|
||||
echo '\midrule'
|
||||
|
||||
tail -n +2 "${FINAL_CSV}" | while IFS=',' read -r \
|
||||
entities ticks wall hz ptw ingest sim export diag \
|
||||
faults lockouts expmt acks alts rss; do
|
||||
printf '%s & %s & %s & %s & %s \\\\\n' \
|
||||
"$(printf '%s' "${entities}" | sed 's/000$/k/' | sed 's/00k$/00k/')" \
|
||||
"${rss}" "${hz}" "${ptw}" "${sim}"
|
||||
done
|
||||
|
||||
echo '\bottomrule'
|
||||
echo '\end{tabular}'
|
||||
echo '\end{table}'
|
||||
echo ""
|
||||
echo "Done. $(date -u)"
|
||||
935
src/main.rs
Normal file
935
src/main.rs
Normal file
@@ -0,0 +1,935 @@
|
||||
/// ============================================================
|
||||
/// ECS Digital Twin Benchmark — TRANSIT lab / UQAC
|
||||
/// Target paper: "ECS as a Natural Runtime Substrate for
|
||||
/// Industrial Digital Twins" (IEEE SWC 2026)
|
||||
///
|
||||
/// Three asset archetypes mirror the three DT data tiers:
|
||||
/// Tier 1 — SensorAsset (70 %): ephemeral high-frequency readings
|
||||
/// Tier 2 — EventAsset (20 %): threshold / fault events
|
||||
/// Tier 3 — ActuatorAsset (10 %): commanded state with ack tracking
|
||||
///
|
||||
/// Five systems run per tick in a fixed schedule:
|
||||
/// 1. FaultInjectionSystem — drives archetype mutations
|
||||
/// 2. IngestSystem — writes fresh sensor / command data
|
||||
/// 3. SimulationSystem — processes state (heaviest, par_iter)
|
||||
/// 4. ExportSystem — read-only shadow-model pass
|
||||
/// 5. DiagnosticsSystem — per-system timing + RSS sampling
|
||||
///
|
||||
/// Usage:
|
||||
/// cargo run --release -- --entities 100000 --ticks 5000
|
||||
/// cargo run --release -- --entities 200000 --ticks 2000
|
||||
/// ============================================================
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use bevy_ecs::prelude::*;
|
||||
use rand::{Rng, SeedableRng};
|
||||
use rand_chacha::ChaCha8Rng;
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// CLI args (no clap dependency — keep compile times short)
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
struct Config {
|
||||
total_entities: usize,
|
||||
ticks: u32,
|
||||
warmup_ticks: u32,
|
||||
rng_seed: u64,
|
||||
fault_probability: f32,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
total_entities: 100_000,
|
||||
ticks: 5_000,
|
||||
warmup_ticks: 500,
|
||||
rng_seed: 0xDEAD_BEEF_CAFE_BABE,
|
||||
fault_probability: 0.02,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_args() -> Config {
|
||||
let mut cfg = Config::default();
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
let mut i = 1;
|
||||
while i < args.len() {
|
||||
match args[i].as_str() {
|
||||
"--entities" => {
|
||||
cfg.total_entities = args[i + 1].parse().expect("bad --entities");
|
||||
i += 2;
|
||||
}
|
||||
"--ticks" => {
|
||||
cfg.ticks = args[i + 1].parse().expect("bad --ticks");
|
||||
i += 2;
|
||||
}
|
||||
"--seed" => {
|
||||
cfg.rng_seed = args[i + 1].parse().expect("bad --seed");
|
||||
i += 2;
|
||||
}
|
||||
"--fault-prob" => {
|
||||
cfg.fault_probability = args[i + 1].parse().expect("bad --fault-prob");
|
||||
i += 2;
|
||||
}
|
||||
_ => {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
cfg
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// Enums
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum AssetClass {
|
||||
Sensor,
|
||||
Event,
|
||||
Actuator,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum SensorUnit {
|
||||
Temperature,
|
||||
Vibration,
|
||||
Position,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum AlertSeverity {
|
||||
Warning,
|
||||
Critical,
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// Components — shared
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
/// Pure identity — every entity carries this, no behaviour.
|
||||
#[derive(Component)]
|
||||
struct AssetId {
|
||||
id: u32,
|
||||
class: AssetClass,
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// Components — Tier 1 SensorAsset
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
/// Written by IngestSystem, read by SimulationSystem.
|
||||
/// Removed / re-added by FaultInjectionSystem to model sensor dropout.
|
||||
/// Its *absence* is the fault representation — no null fields, no enums.
|
||||
#[derive(Component)]
|
||||
struct RawSensorData {
|
||||
value: f32,
|
||||
timestamp_us: u64,
|
||||
sequence_number: u32,
|
||||
}
|
||||
|
||||
/// Written by SimulationSystem, read by ExportSystem.
|
||||
/// Never removed — persists as the last-known-good state even during dropout.
|
||||
#[derive(Component)]
|
||||
struct ProcessedState {
|
||||
filtered_value: f32,
|
||||
last_updated_tick: u32,
|
||||
}
|
||||
|
||||
/// Static config — written once at spawn, never mutated.
|
||||
#[derive(Component)]
|
||||
struct SensorMetadata {
|
||||
sample_rate_hz: f32,
|
||||
unit: SensorUnit,
|
||||
calibration_offset: f32,
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// Components — Tier 2 EventAsset
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
/// Static threshold config — written once at spawn.
|
||||
#[derive(Component)]
|
||||
struct ThresholdConfig {
|
||||
upper_bound: f32,
|
||||
lower_bound: f32,
|
||||
consecutive_violations_required: u8,
|
||||
}
|
||||
|
||||
/// Mutable per-tick state tracked by SimulationSystem.
|
||||
#[derive(Component)]
|
||||
struct ThresholdState {
|
||||
current_violation_count: u8,
|
||||
last_violation_tick: u32,
|
||||
is_alerting: bool,
|
||||
}
|
||||
|
||||
/// Added by SimulationSystem when threshold is breached.
|
||||
/// Removed when condition clears. Presence = active alert.
|
||||
#[derive(Component)]
|
||||
struct AlertEvent {
|
||||
severity: AlertSeverity,
|
||||
triggered_at_tick: u32,
|
||||
asset_id: u32,
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// Components — Tier 3 ActuatorAsset
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
/// Written by SimulationSystem each tick (lerp toward setpoint).
|
||||
#[derive(Component)]
|
||||
struct ActuatorState {
|
||||
current_setpoint: f32,
|
||||
actual_position: f32,
|
||||
last_command_tick: u32,
|
||||
}
|
||||
|
||||
/// Written by IngestSystem (new command arrives).
|
||||
/// Cleared by ExportSystem after ack is read.
|
||||
/// Removed by FaultInjectionSystem when consecutive_failures >= 5.
|
||||
#[derive(Component)]
|
||||
struct CommandBuffer {
|
||||
pending_setpoint: Option<f32>,
|
||||
acknowledged: bool,
|
||||
}
|
||||
|
||||
/// Written by SimulationSystem when actuator fails to converge.
|
||||
#[derive(Component)]
|
||||
struct ActuatorHealth {
|
||||
fault_code: Option<u8>,
|
||||
consecutive_failures: u8,
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// Resources
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
/// Current tick counter — its own resource so systems can take
|
||||
/// Res<CurrentTick> without conflicting with ResMut<TickDiagnostics>.
|
||||
#[derive(Resource, Default)]
|
||||
struct CurrentTick(u32);
|
||||
|
||||
/// Per-system timing accumulated across the measurement window.
|
||||
/// Written exclusively by each system that records its own elapsed time,
|
||||
/// and by DiagnosticsSystem which resets and prints the window.
|
||||
/// No system takes both Res<TickDiagnostics> and ResMut<TickDiagnostics>.
|
||||
#[derive(Resource, Default)]
|
||||
struct TickDiagnostics {
|
||||
system_elapsed_us: HashMap<&'static str, u64>,
|
||||
accumulated_elapsed_us: HashMap<&'static str, u64>,
|
||||
ticks_in_window: u32,
|
||||
total_tick_elapsed_us: u64,
|
||||
}
|
||||
|
||||
impl TickDiagnostics {
|
||||
fn record(&mut self, name: &'static str, elapsed: Duration) {
|
||||
let us = elapsed.as_micros() as u64;
|
||||
self.system_elapsed_us.insert(name, us);
|
||||
*self.accumulated_elapsed_us.entry(name).or_insert(0) += us;
|
||||
}
|
||||
}
|
||||
|
||||
/// Fault injection configuration and deterministic RNG.
|
||||
#[derive(Resource)]
|
||||
struct FaultProfile {
|
||||
fault_probability_per_tick: f32,
|
||||
rng: ChaCha8Rng,
|
||||
total_faults_injected: u32,
|
||||
total_actuator_lockouts: u32,
|
||||
}
|
||||
|
||||
impl FaultProfile {
|
||||
fn new(seed: u64, probability: f32) -> Self {
|
||||
Self {
|
||||
fault_probability_per_tick: probability,
|
||||
rng: ChaCha8Rng::seed_from_u64(seed),
|
||||
total_faults_injected: 0,
|
||||
total_actuator_lockouts: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Monotonically increasing simulated clock in microseconds.
|
||||
#[derive(Resource, Default)]
|
||||
struct SimClock {
|
||||
current_us: u64,
|
||||
step_us: u64,
|
||||
}
|
||||
|
||||
/// Accumulates total "exported" bytes for throughput reporting.
|
||||
#[derive(Resource, Default)]
|
||||
struct ExportCounter {
|
||||
total_bytes: u64,
|
||||
total_alerts_seen: u32,
|
||||
total_acks_processed: u32,
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// System labels
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
|
||||
enum DtSystemSet {
|
||||
Fault,
|
||||
Ingest,
|
||||
Simulate,
|
||||
Export,
|
||||
Diagnostics,
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// System 1 — FaultInjectionSystem
|
||||
//
|
||||
// Drives all archetype mutations.
|
||||
// Runs BEFORE Ingest and Simulate so they see the updated archetypes.
|
||||
//
|
||||
// SensorAsset with RawSensorData → roll to REMOVE it (dropout)
|
||||
// SensorAsset without RawSensorData → roll to RE-ADD it (recovery)
|
||||
// ActuatorAsset with consecutive_failures >= 5 → remove CommandBuffer
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
fn fault_injection_system(
|
||||
mut commands: Commands,
|
||||
mut profile: ResMut<FaultProfile>,
|
||||
active_sensors: Query<
|
||||
Entity,
|
||||
(With<RawSensorData>, With<SensorMetadata>),
|
||||
>,
|
||||
inactive_sensors: Query<
|
||||
(Entity, &SensorMetadata),
|
||||
(Without<RawSensorData>, With<ProcessedState>),
|
||||
>,
|
||||
actuators: Query<(Entity, &ActuatorHealth), With<CommandBuffer>>,
|
||||
) {
|
||||
let p = profile.fault_probability_per_tick;
|
||||
|
||||
for entity in active_sensors.iter() {
|
||||
if profile.rng.gen::<f32>() < p {
|
||||
commands.entity(entity).remove::<RawSensorData>();
|
||||
profile.total_faults_injected += 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (entity, meta) in inactive_sensors.iter() {
|
||||
if profile.rng.gen::<f32>() < p {
|
||||
commands.entity(entity).insert(RawSensorData {
|
||||
value: meta.calibration_offset,
|
||||
timestamp_us: 0,
|
||||
sequence_number: 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (entity, health) in actuators.iter() {
|
||||
if health.consecutive_failures >= 5 {
|
||||
commands.entity(entity).remove::<CommandBuffer>();
|
||||
profile.total_actuator_lockouts += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// System 2 — IngestSystem
|
||||
//
|
||||
// Write set : RawSensorData, CommandBuffer
|
||||
// Read set : SensorMetadata, SimClock, CurrentTick
|
||||
// Disjoint from ExportSystem write set → Bevy can schedule in parallel.
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
fn ingest_system(
|
||||
mut sensors: Query<(&SensorMetadata, &mut RawSensorData)>,
|
||||
mut actuators: Query<&mut CommandBuffer>,
|
||||
clock: Res<SimClock>,
|
||||
mut profile: ResMut<FaultProfile>,
|
||||
mut diag: ResMut<TickDiagnostics>,
|
||||
) {
|
||||
let t0 = Instant::now();
|
||||
|
||||
for (meta, mut raw) in sensors.iter_mut() {
|
||||
raw.sequence_number = raw.sequence_number.wrapping_add(1);
|
||||
let phase = raw.sequence_number as f32 / meta.sample_rate_hz;
|
||||
raw.value = (phase * std::f32::consts::TAU).sin() + meta.calibration_offset;
|
||||
raw.timestamp_us = clock.current_us;
|
||||
}
|
||||
|
||||
let command_probability: f32 = 0.05;
|
||||
for mut buf in actuators.iter_mut() {
|
||||
if profile.rng.gen::<f32>() < command_probability {
|
||||
buf.pending_setpoint = Some(profile.rng.gen_range(-1.0_f32..1.0_f32));
|
||||
buf.acknowledged = false;
|
||||
}
|
||||
}
|
||||
|
||||
diag.record("IngestSystem", t0.elapsed());
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// System 3 — SimulationSystem
|
||||
//
|
||||
// Write set : ProcessedState, ThresholdState, ActuatorState,
|
||||
// ActuatorHealth, Commands (AlertEvent inserts/removes)
|
||||
// Read set : RawSensorData, SensorMetadata, ThresholdConfig,
|
||||
// CommandBuffer, CurrentTick
|
||||
//
|
||||
// Takes Res<CurrentTick> (not TickDiagnostics) to read the tick number,
|
||||
// then ResMut<TickDiagnostics> only to record its elapsed time.
|
||||
// No Res/ResMut conflict.
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
fn simulation_system(
|
||||
mut commands: Commands,
|
||||
tick_res: Res<CurrentTick>,
|
||||
// Pass (a): only entities WITH RawSensorData are matched.
|
||||
// Dropout entities are skipped automatically by the query filter.
|
||||
mut sensors: Query<(
|
||||
&RawSensorData,
|
||||
&SensorMetadata,
|
||||
&mut ProcessedState,
|
||||
)>,
|
||||
// Pass (b): threshold evaluation — also requires RawSensorData.
|
||||
mut events: Query<(
|
||||
Entity,
|
||||
&AssetId,
|
||||
&RawSensorData,
|
||||
&ThresholdConfig,
|
||||
&mut ThresholdState,
|
||||
Option<&AlertEvent>,
|
||||
)>,
|
||||
// Pass (c): actuator convergence.
|
||||
mut actuators: Query<(
|
||||
&mut ActuatorState,
|
||||
&mut ActuatorHealth,
|
||||
Option<&mut CommandBuffer>,
|
||||
)>,
|
||||
mut diag: ResMut<TickDiagnostics>,
|
||||
) {
|
||||
let t0 = Instant::now();
|
||||
let tick = tick_res.0;
|
||||
let alpha = 0.1_f32;
|
||||
|
||||
// ── (a) Sensor EMA — par_iter_mut, independent per entity ────
|
||||
sensors.par_iter_mut().for_each(|(raw, _meta, mut ps)| {
|
||||
ps.filtered_value =
|
||||
alpha * raw.value + (1.0 - alpha) * ps.filtered_value;
|
||||
ps.last_updated_tick = tick;
|
||||
});
|
||||
|
||||
// ── (b) Threshold evaluation ──────────────────────────────────
|
||||
for (entity, id, raw, cfg, mut state, maybe_alert) in events.iter_mut() {
|
||||
let out_of_bounds =
|
||||
raw.value > cfg.upper_bound || raw.value < cfg.lower_bound;
|
||||
|
||||
if out_of_bounds {
|
||||
state.current_violation_count =
|
||||
state.current_violation_count.saturating_add(1);
|
||||
state.last_violation_tick = tick;
|
||||
|
||||
if state.current_violation_count >= cfg.consecutive_violations_required
|
||||
&& maybe_alert.is_none()
|
||||
{
|
||||
let severity = if state.current_violation_count >= 10 {
|
||||
AlertSeverity::Critical
|
||||
} else {
|
||||
AlertSeverity::Warning
|
||||
};
|
||||
commands.entity(entity).insert(AlertEvent {
|
||||
severity,
|
||||
triggered_at_tick: tick,
|
||||
asset_id: id.id,
|
||||
});
|
||||
state.is_alerting = true;
|
||||
}
|
||||
} else {
|
||||
state.current_violation_count = 0;
|
||||
if maybe_alert.is_some() {
|
||||
commands.entity(entity).remove::<AlertEvent>();
|
||||
state.is_alerting = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── (c) Actuator convergence ──────────────────────────────────
|
||||
let lerp_rate = 0.1_f32;
|
||||
let tolerance = 0.001_f32;
|
||||
let failure_thresh = 200_u32;
|
||||
|
||||
for (mut state, mut health, maybe_buf) in actuators.iter_mut() {
|
||||
if let Some(mut buf) = maybe_buf {
|
||||
if let Some(setpoint) = buf.pending_setpoint {
|
||||
state.current_setpoint = setpoint;
|
||||
state.last_command_tick = tick;
|
||||
}
|
||||
buf.acknowledged = true;
|
||||
}
|
||||
|
||||
let delta = state.current_setpoint - state.actual_position;
|
||||
state.actual_position += delta * lerp_rate;
|
||||
|
||||
if delta.abs() < tolerance {
|
||||
health.consecutive_failures = 0;
|
||||
health.fault_code = None;
|
||||
} else if tick.wrapping_sub(state.last_command_tick) > failure_thresh {
|
||||
health.consecutive_failures =
|
||||
health.consecutive_failures.saturating_add(1);
|
||||
health.fault_code = Some(0x01);
|
||||
}
|
||||
}
|
||||
|
||||
diag.record("SimulationSystem", t0.elapsed());
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// System 4 — ExportSystem
|
||||
//
|
||||
// Read set : ProcessedState, AlertEvent, ActuatorState, CommandBuffer
|
||||
// Write set : CommandBuffer (ack clear), ExportCounter
|
||||
//
|
||||
// Entity data writes are limited to CommandBuffer.acknowledged/pending_setpoint.
|
||||
// ProcessedState and ActuatorState are read-only, so Bevy can overlap
|
||||
// this system with IngestSystem (which writes RawSensorData only).
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
fn export_system(
|
||||
processed: Query<&ProcessedState>,
|
||||
alerts: Query<&AlertEvent>,
|
||||
// Single query covering all actuator data — avoids the B0001 conflict
|
||||
// that arises from having separate Res<CommandBuffer> and
|
||||
// ResMut<CommandBuffer> queries in the same system.
|
||||
mut actuators: Query<(&ActuatorState, &mut CommandBuffer)>,
|
||||
// Actuator entities that have lost their CommandBuffer (locked out).
|
||||
locked_actuators: Query<&ActuatorState, Without<CommandBuffer>>,
|
||||
mut counter: ResMut<ExportCounter>,
|
||||
mut diag: ResMut<TickDiagnostics>,
|
||||
) {
|
||||
let t0 = Instant::now();
|
||||
let mut exported: u64 = 0;
|
||||
|
||||
// Shadow export for all entities with ProcessedState.
|
||||
for ps in processed.iter() {
|
||||
let _ = std::hint::black_box((ps.filtered_value, ps.last_updated_tick));
|
||||
exported += 8;
|
||||
}
|
||||
|
||||
// Alert export.
|
||||
for alert in alerts.iter() {
|
||||
let _ = std::hint::black_box((alert.severity, alert.triggered_at_tick));
|
||||
exported += 8;
|
||||
counter.total_alerts_seen += 1;
|
||||
}
|
||||
|
||||
// Actuator shadow export + ack processing in a single pass.
|
||||
for (state, mut buf) in actuators.iter_mut() {
|
||||
let _ = std::hint::black_box(state.actual_position);
|
||||
exported += 4;
|
||||
if buf.acknowledged {
|
||||
counter.total_acks_processed += 1;
|
||||
exported += 1;
|
||||
// Clear ack post-export — Tier 3 round-trip complete.
|
||||
buf.pending_setpoint = None;
|
||||
buf.acknowledged = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Locked-out actuators (no CommandBuffer) still get shadow-exported.
|
||||
for state in locked_actuators.iter() {
|
||||
let _ = std::hint::black_box(state.actual_position);
|
||||
exported += 4;
|
||||
}
|
||||
|
||||
counter.total_bytes += exported;
|
||||
diag.record("ExportSystem", t0.elapsed());
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// System 5 — DiagnosticsSystem
|
||||
//
|
||||
// Runs last. Every 1 000 ticks prints a structured summary line,
|
||||
// then resets the accumulation window.
|
||||
//
|
||||
// Takes ResMut<TickDiagnostics> only — no Res<TickDiagnostics>.
|
||||
// Takes Res<CurrentTick> for the tick number.
|
||||
// No Res/ResMut conflict on any resource.
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
fn rss_bytes() -> u64 {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
if let Ok(status) = fs::read_to_string("/proc/self/status") {
|
||||
for line in status.lines() {
|
||||
if line.starts_with("VmRSS:") {
|
||||
let kb: u64 = line
|
||||
.split_whitespace()
|
||||
.nth(1)
|
||||
.and_then(|s| s.parse().ok())
|
||||
.unwrap_or(0);
|
||||
return kb * 1024;
|
||||
}
|
||||
}
|
||||
}
|
||||
0
|
||||
}
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
{
|
||||
// macOS: use proc_info via /proc is unavailable.
|
||||
// Read vm_stat or just return 0 — the paper numbers come from Linux.
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
fn diagnostics_system(
|
||||
tick_res: Res<CurrentTick>,
|
||||
mut diag: ResMut<TickDiagnostics>,
|
||||
counter: Res<ExportCounter>,
|
||||
profile: Res<FaultProfile>,
|
||||
n_with_sensor: Query<(), With<RawSensorData>>,
|
||||
n_all_processed: Query<(), With<ProcessedState>>,
|
||||
n_alerts: Query<(), With<AlertEvent>>,
|
||||
n_actuators: Query<(), With<ActuatorState>>,
|
||||
) {
|
||||
let t0 = Instant::now();
|
||||
let tick = tick_res.0;
|
||||
|
||||
diag.ticks_in_window += 1;
|
||||
|
||||
if tick % 1_000 != 0 || diag.ticks_in_window == 0 {
|
||||
diag.record("DiagnosticsSystem", t0.elapsed());
|
||||
return;
|
||||
}
|
||||
|
||||
let n = diag.ticks_in_window as f64;
|
||||
let rss = rss_bytes();
|
||||
|
||||
let mean = |name: &'static str| -> f64 {
|
||||
diag.accumulated_elapsed_us
|
||||
.get(name)
|
||||
.copied()
|
||||
.unwrap_or(0) as f64
|
||||
/ n
|
||||
};
|
||||
|
||||
let mean_tick_us = diag.total_tick_elapsed_us as f64 / n;
|
||||
|
||||
println!(
|
||||
"tick={tick:>7} | \
|
||||
entities={ne:>7} (sensor_active={sa:>6}, alerts={al:>4}, act={ac:>5}) | \
|
||||
faults={fi:>6} lockouts={lo:>3} | \
|
||||
rss={rss_mb:>6.1} MB | \
|
||||
tick_mean={tm:>7.1} µs | \
|
||||
ingest={ig:>6.1} sim={sm:>6.1} export={ex:>6.1} diag={dg:>5.1} µs | \
|
||||
exported={eb:.2} MB acks={acks}",
|
||||
tick = tick,
|
||||
ne = n_all_processed.iter().count(),
|
||||
sa = n_with_sensor.iter().count(),
|
||||
al = n_alerts.iter().count(),
|
||||
ac = n_actuators.iter().count(),
|
||||
fi = profile.total_faults_injected,
|
||||
lo = profile.total_actuator_lockouts,
|
||||
rss_mb = rss as f64 / 1_048_576.0,
|
||||
tm = mean_tick_us,
|
||||
ig = mean("IngestSystem"),
|
||||
sm = mean("SimulationSystem"),
|
||||
ex = mean("ExportSystem"),
|
||||
dg = mean("DiagnosticsSystem"),
|
||||
eb = counter.total_bytes as f64 / 1_048_576.0,
|
||||
acks = counter.total_acks_processed,
|
||||
);
|
||||
|
||||
// Reset window.
|
||||
diag.accumulated_elapsed_us.clear();
|
||||
diag.ticks_in_window = 0;
|
||||
diag.total_tick_elapsed_us = 0;
|
||||
|
||||
diag.record("DiagnosticsSystem", t0.elapsed());
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// World setup — entity spawning
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
fn spawn_entities(world: &mut World, cfg: &Config) {
|
||||
let mut rng = ChaCha8Rng::seed_from_u64(cfg.rng_seed ^ 0x1234);
|
||||
|
||||
let n_sensor = (cfg.total_entities as f32 * 0.70).round() as usize;
|
||||
let n_event = (cfg.total_entities as f32 * 0.20).round() as usize;
|
||||
let n_actuator = cfg.total_entities - n_sensor - n_event;
|
||||
|
||||
let sensor_units = [
|
||||
SensorUnit::Temperature,
|
||||
SensorUnit::Vibration,
|
||||
SensorUnit::Position,
|
||||
];
|
||||
|
||||
// ── Tier 1: SensorAsset ──────────────────────────────────
|
||||
// spawn_batch keeps all components for the same archetype contiguous
|
||||
// in memory — exactly the cache-coherent layout claimed in the paper.
|
||||
world.spawn_batch((0..n_sensor).map(|i| {
|
||||
let unit = sensor_units[i % 3];
|
||||
let rate = 10.0_f32 + (i % 90) as f32;
|
||||
let offset = {
|
||||
// Pull from rng in closure — ChaCha8Rng is not Send so we
|
||||
// can't move it into par_iter; instead we precompute offsets
|
||||
// sequentially here then use them in the batch.
|
||||
// For the spawn batch we use a simple deterministic formula
|
||||
// instead of rng to avoid borrow issues inside the closure.
|
||||
((i as f32 * 0.6180339887) % 1.0) - 0.5
|
||||
};
|
||||
(
|
||||
AssetId { id: i as u32, class: AssetClass::Sensor },
|
||||
SensorMetadata {
|
||||
sample_rate_hz: rate,
|
||||
unit,
|
||||
calibration_offset: offset,
|
||||
},
|
||||
RawSensorData {
|
||||
value: offset,
|
||||
timestamp_us: 0,
|
||||
sequence_number: 0,
|
||||
},
|
||||
ProcessedState {
|
||||
filtered_value: offset,
|
||||
last_updated_tick: 0,
|
||||
},
|
||||
)
|
||||
}));
|
||||
|
||||
// ── Tier 2: EventAsset ───────────────────────────────────
|
||||
let base = n_sensor;
|
||||
// Staggered thresholds — prevents all entities from triggering at once.
|
||||
world.spawn_batch((0..n_event).map(|i| {
|
||||
let spread = (i % 20) as f32 * 0.05;
|
||||
let upper = 0.6 + spread;
|
||||
let lower = -0.6 - spread;
|
||||
let consec = 2 + (i % 8) as u8;
|
||||
let offset = ((i as f32 * 0.7320508) % 1.0) - 0.5;
|
||||
(
|
||||
AssetId { id: (base + i) as u32, class: AssetClass::Event },
|
||||
SensorMetadata {
|
||||
sample_rate_hz: 5.0 + (i % 10) as f32,
|
||||
unit: SensorUnit::Temperature,
|
||||
calibration_offset: offset * 0.1,
|
||||
},
|
||||
RawSensorData {
|
||||
value: 0.0,
|
||||
timestamp_us: 0,
|
||||
sequence_number: 0,
|
||||
},
|
||||
ProcessedState {
|
||||
filtered_value: 0.0,
|
||||
last_updated_tick: 0,
|
||||
},
|
||||
ThresholdConfig {
|
||||
upper_bound: upper,
|
||||
lower_bound: lower,
|
||||
consecutive_violations_required: consec,
|
||||
},
|
||||
ThresholdState {
|
||||
current_violation_count: 0,
|
||||
last_violation_tick: 0,
|
||||
is_alerting: false,
|
||||
},
|
||||
)
|
||||
}));
|
||||
|
||||
// ── Tier 3: ActuatorAsset ────────────────────────────────
|
||||
let base = n_sensor + n_event;
|
||||
// Use rng for actuator initial positions (small count, no closure issue).
|
||||
let actuator_inits: Vec<f32> = (0..n_actuator)
|
||||
.map(|_| rng.gen_range(-1.0_f32..1.0_f32))
|
||||
.collect();
|
||||
|
||||
world.spawn_batch((0..n_actuator).map(|i| {
|
||||
let init_pos = actuator_inits[i];
|
||||
(
|
||||
AssetId { id: (base + i) as u32, class: AssetClass::Actuator },
|
||||
ActuatorState {
|
||||
current_setpoint: init_pos,
|
||||
actual_position: init_pos,
|
||||
last_command_tick: 0,
|
||||
},
|
||||
CommandBuffer {
|
||||
pending_setpoint: None,
|
||||
acknowledged: false,
|
||||
},
|
||||
ActuatorHealth {
|
||||
fault_code: None,
|
||||
consecutive_failures: 0,
|
||||
},
|
||||
// ProcessedState on actuators lets ExportSystem's ProcessedState
|
||||
// query count all tiers unambiguously.
|
||||
ProcessedState {
|
||||
filtered_value: init_pos,
|
||||
last_updated_tick: 0,
|
||||
},
|
||||
)
|
||||
}));
|
||||
|
||||
println!(
|
||||
"[spawn] SensorAsset={n_sensor} EventAsset={n_event} \
|
||||
ActuatorAsset={n_actuator} total={}",
|
||||
n_sensor + n_event + n_actuator
|
||||
);
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// Schedule construction
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
fn build_schedule() -> Schedule {
|
||||
let mut schedule = Schedule::default();
|
||||
|
||||
schedule.configure_sets((
|
||||
DtSystemSet::Fault,
|
||||
DtSystemSet::Ingest,
|
||||
DtSystemSet::Simulate,
|
||||
DtSystemSet::Export,
|
||||
DtSystemSet::Diagnostics,
|
||||
).chain());
|
||||
|
||||
schedule.add_systems((
|
||||
fault_injection_system.in_set(DtSystemSet::Fault),
|
||||
ingest_system .in_set(DtSystemSet::Ingest),
|
||||
simulation_system .in_set(DtSystemSet::Simulate),
|
||||
export_system .in_set(DtSystemSet::Export),
|
||||
diagnostics_system .in_set(DtSystemSet::Diagnostics),
|
||||
));
|
||||
|
||||
schedule
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// Main
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
fn main() {
|
||||
let cfg = parse_args();
|
||||
|
||||
println!(
|
||||
"ECS Digital Twin Benchmark — TRANSIT lab / UQAC\n\
|
||||
entities={} | ticks={} | warmup={} | fault_prob={:.1}%",
|
||||
cfg.total_entities,
|
||||
cfg.ticks,
|
||||
cfg.warmup_ticks,
|
||||
cfg.fault_probability * 100.0,
|
||||
);
|
||||
|
||||
let mut world = World::new();
|
||||
let mut schedule = build_schedule();
|
||||
|
||||
// Insert all resources before spawning.
|
||||
world.insert_resource(CurrentTick(0));
|
||||
world.insert_resource(FaultProfile::new(cfg.rng_seed, cfg.fault_probability));
|
||||
world.insert_resource(SimClock { current_us: 0, step_us: 1_000 });
|
||||
world.insert_resource(TickDiagnostics::default());
|
||||
world.insert_resource(ExportCounter::default());
|
||||
|
||||
spawn_entities(&mut world, &cfg);
|
||||
|
||||
// ── Warmup ───────────────────────────────────────────────
|
||||
println!("[warmup] running {} ticks...", cfg.warmup_ticks);
|
||||
for i in 0..cfg.warmup_ticks {
|
||||
world.resource_mut::<CurrentTick>().0 = i;
|
||||
world.resource_mut::<SimClock>().current_us += 1_000;
|
||||
schedule.run(&mut world);
|
||||
}
|
||||
|
||||
// Reset all measurement state so warmup doesn't pollute results.
|
||||
{
|
||||
let mut diag = world.resource_mut::<TickDiagnostics>();
|
||||
diag.accumulated_elapsed_us.clear();
|
||||
diag.ticks_in_window = 0;
|
||||
diag.total_tick_elapsed_us = 0;
|
||||
}
|
||||
{
|
||||
let mut ctr = world.resource_mut::<ExportCounter>();
|
||||
ctr.total_bytes = 0;
|
||||
ctr.total_acks_processed = 0;
|
||||
ctr.total_alerts_seen = 0;
|
||||
}
|
||||
|
||||
println!("[warmup] done — starting measurement ({} ticks)", cfg.ticks);
|
||||
|
||||
// ── Measurement loop ─────────────────────────────────────
|
||||
let run_start = Instant::now();
|
||||
|
||||
for i in 0..cfg.ticks {
|
||||
let tick_id = cfg.warmup_ticks + i;
|
||||
|
||||
world.resource_mut::<CurrentTick>().0 = tick_id;
|
||||
world.resource_mut::<SimClock>().current_us += 1_000;
|
||||
|
||||
// Time the full tick including all five systems.
|
||||
let tick_wall = Instant::now();
|
||||
schedule.run(&mut world);
|
||||
let tick_elapsed = tick_wall.elapsed();
|
||||
|
||||
world.resource_mut::<TickDiagnostics>().total_tick_elapsed_us +=
|
||||
tick_elapsed.as_micros() as u64;
|
||||
}
|
||||
|
||||
let total_elapsed = run_start.elapsed();
|
||||
|
||||
// ── Final summary ─────────────────────────────────────────
|
||||
let hz = cfg.ticks as f64 / total_elapsed.as_secs_f64();
|
||||
|
||||
// Borrow resources for final print.
|
||||
let diag = world.resource::<TickDiagnostics>();
|
||||
let counter = world.resource::<ExportCounter>();
|
||||
let profile = world.resource::<FaultProfile>();
|
||||
|
||||
let n = diag.ticks_in_window.max(1) as f64;
|
||||
let mean = |name: &'static str| -> f64 {
|
||||
diag.accumulated_elapsed_us
|
||||
.get(name)
|
||||
.copied()
|
||||
.unwrap_or(0) as f64
|
||||
/ n
|
||||
};
|
||||
let mean_tick_us = diag.total_tick_elapsed_us as f64
|
||||
/ cfg.ticks as f64;
|
||||
|
||||
println!(
|
||||
"\n── Final Summary ──────────────────────────────────────\n\
|
||||
Total ticks (measurement): {ticks}\n\
|
||||
Total wall time: {wall:.3} s\n\
|
||||
Sustained tick rate: {hz:.1} Hz\n\
|
||||
Per-tick mean (wall): {ptw:.1} µs\n\
|
||||
\n\
|
||||
Per-system mean (µs):\n\
|
||||
IngestSystem: {ig:.1}\n\
|
||||
SimulationSystem: {sm:.1}\n\
|
||||
ExportSystem: {ex:.1}\n\
|
||||
DiagnosticsSystem: {dg:.1}\n\
|
||||
\n\
|
||||
Fault injection:\n\
|
||||
Total sensor faults: {fi}\n\
|
||||
Total actuator lockouts: {lo}\n\
|
||||
\n\
|
||||
Export totals:\n\
|
||||
Bytes exported: {eb:.2} MB\n\
|
||||
Acks processed: {acks}\n\
|
||||
Alerts seen: {alts}\n\
|
||||
\n\
|
||||
Memory (RSS at end): {rss:.1} MB\n\
|
||||
────────────────────────────────────────────────────────",
|
||||
ticks = cfg.ticks,
|
||||
wall = total_elapsed.as_secs_f64(),
|
||||
hz = hz,
|
||||
ptw = mean_tick_us,
|
||||
ig = mean("IngestSystem"),
|
||||
sm = mean("SimulationSystem"),
|
||||
ex = mean("ExportSystem"),
|
||||
dg = mean("DiagnosticsSystem"),
|
||||
fi = profile.total_faults_injected,
|
||||
lo = profile.total_actuator_lockouts,
|
||||
eb = counter.total_bytes as f64 / 1_048_576.0,
|
||||
acks = counter.total_acks_processed,
|
||||
alts = counter.total_alerts_seen,
|
||||
rss = rss_bytes() as f64 / 1_048_576.0,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user