From 3e321260caec7b6e0841ed4fffbd7099d10315e6 Mon Sep 17 00:00:00 2001 From: Sebastian Bernauer Date: Thu, 30 May 2024 18:19:53 +0200 Subject: [PATCH 1/5] feat: Improve performance by memadvising sequential access --- Cargo.lock | 221 ++++++++++++++++++++++++++++----------- Cargo.toml | 3 +- breakwater/Cargo.toml | 1 + breakwater/src/server.rs | 17 ++- 4 files changed, 178 insertions(+), 64 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e77e42c..b4871d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,9 @@ checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -116,9 +116,9 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.71" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11" dependencies = [ "addr2line", "cc", @@ -181,6 +181,7 @@ dependencies = [ "const_format", "env_logger", "log", + "memadvise", "number_prefix", "prometheus_exporter", "rstest", @@ -254,9 +255,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.97" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" [[package]] name = "cexpr" @@ -328,9 +329,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.7.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" +checksum = "f803f94ecf597339c7a34eed2036ef83f86aaba937f001f7c5b5e251f043f1f9" dependencies = [ "glob", "libc", @@ -365,7 +366,7 @@ version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn", @@ -417,9 +418,9 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if 1.0.0", ] @@ -483,9 +484,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -504,9 +505,9 @@ dependencies = [ [[package]] name = "either" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "enum_dispatch" @@ -543,6 +544,12 @@ dependencies = [ "log", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.3.9" @@ -730,9 +737,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "glob" @@ -751,10 +758,10 @@ dependencies = [ ] [[package]] -name = "heck" -version = "0.4.1" +name = "hashbrown" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" @@ -834,6 +841,16 @@ dependencies = [ "tiff", ] +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "is-terminal" version = "0.4.12" @@ -893,6 +910,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -913,9 +940,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" -version = "0.2.154" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" @@ -929,9 +956,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" @@ -949,6 +976,18 @@ version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +[[package]] +name = "memadvise" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf6f86f067270b307b65d17080ac0eac2afd247d60f49646db200c9b8680cf4" +dependencies = [ + "kernel32-sys", + "libc", + "page_size", + "winapi 0.2.8", +] + [[package]] name = "memchr" version = "2.7.2" @@ -963,9 +1002,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" dependencies = [ "adler", "simd-adler32", @@ -990,7 +1029,7 @@ checksum = "b13b648036a2339d06de780866fbdfda0dde886de7b3af2ddeba8b14f4ee34ac" dependencies = [ "cfg-if 0.1.10", "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1036,9 +1075,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.32.2" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" dependencies = [ "memchr", ] @@ -1064,11 +1103,21 @@ dependencies = [ "ttf-parser", ] +[[package]] +name = "page_size" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eebde548fbbf1ea81a99b128872779c437752fb99f217c45245e1a61dcd9edcd" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "parking_lot" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -1126,9 +1175,9 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "plotters" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" dependencies = [ "num-traits", "plotters-backend", @@ -1139,15 +1188,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" +checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" [[package]] name = "plotters-svg" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" dependencies = [ "plotters-backend", ] @@ -1187,11 +1236,20 @@ dependencies = [ "syn", ] +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" -version = "1.0.82" +version = "1.0.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" dependencies = [ "unicode-ident", ] @@ -1338,9 +1396,9 @@ checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "rstest" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5316d2a1479eeef1ea21e7f9ddc67c191d497abc8fc3ba2467857abbb68330" +checksum = "27059f51958c5f8496a6f79511e7c0ac396dd815dc8894e9b6e2efb5779cf6f0" dependencies = [ "futures", "futures-timer", @@ -1350,12 +1408,13 @@ dependencies = [ [[package]] name = "rstest_macros" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04a9df72cc1f67020b0d63ad9bfe4a323e459ea7eb68e03bd9824db49f9a4c25" +checksum = "e6132d64df104c0b3ea7a6ad7766a43f587bd773a4a9cf4cd59296d426afaf3a" dependencies = [ "cfg-if 1.0.0", "glob", + "proc-macro-crate", "proc-macro2", "quote", "regex", @@ -1411,9 +1470,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092474d1a01ea8278f69e6a358998405fae5b8b963ddaeb2b0b04a128bf1dfb0" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" @@ -1444,18 +1503,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.201" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.201" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", @@ -1520,20 +1579,20 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "snafu" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75976f4748ab44f6e5332102be424e7c2dc18daeaf7e725f2040c3ebb133512e" +checksum = "418b8136fec49956eba89be7da2847ec1909df92a9ae4178b5ff0ff092c8d95e" dependencies = [ "snafu-derive", ] [[package]] name = "snafu-derive" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b19911debfb8c2fb1107bc6cb2d61868aaf53a988449213959bb1b5b1ed95f" +checksum = "1a4812a669da00d17d8266a0439eddcacbc88b17f732f927e52eeb9d196f7fb5" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", "syn", @@ -1566,9 +1625,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.63" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", @@ -1577,18 +1636,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.60" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.60" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", @@ -1606,7 +1665,7 @@ dependencies = [ "libc", "log", "rustversion", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1718,6 +1777,23 @@ dependencies = [ "syn", ] +[[package]] +name = "toml_datetime" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + [[package]] name = "trait-variant" version = "0.1.2" @@ -1782,7 +1858,7 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "vncserver" version = "0.2.2" -source = "git+https://github.com/sbernauer/libvnc-rs.git#2bf903ad64c7e33554b011eb05f96c11eadb8821" +source = "git+https://github.com/sbernauer/libvnc-rs.git#2b3418a1f2aa163ec968c0b66b1b025506c3e00e" dependencies = [ "bindgen", "cc", @@ -1887,6 +1963,12 @@ dependencies = [ "rustix", ] +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + [[package]] name = "winapi" version = "0.3.9" @@ -1897,6 +1979,12 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -2066,6 +2154,15 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "zune-inflate" version = "0.2.54" diff --git a/Cargo.toml b/Cargo.toml index e20a857..7c63ecf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,11 +17,12 @@ criterion = {version = "0.5", features = ["async_tokio"]} enum_dispatch = "0.3" env_logger = "0.11" log = "0.4" +memadvise = "0.1" memchr = "2.7" number_prefix = "0.4" pixelbomber = "0.6" prometheus_exporter = "0.8" -rstest = "0.19" +rstest = "0.20" rusttype = "0.9" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/breakwater/Cargo.toml b/breakwater/Cargo.toml index 22a6c86..da30c2d 100644 --- a/breakwater/Cargo.toml +++ b/breakwater/Cargo.toml @@ -20,6 +20,7 @@ clap.workspace = true const_format.workspace = true env_logger.workspace = true log.workspace = true +memadvise.workspace = true number_prefix.workspace = true prometheus_exporter.workspace = true rusttype.workspace = true diff --git a/breakwater/src/server.rs b/breakwater/src/server.rs index c4c3cb1..ef07636 100644 --- a/breakwater/src/server.rs +++ b/breakwater/src/server.rs @@ -4,7 +4,8 @@ use std::{cmp::min, net::IpAddr, sync::Arc, time::Duration}; use breakwater_core::framebuffer::FrameBuffer; use breakwater_parser::{original::OriginalParser, Parser, ParserError}; -use log::{debug, info}; +use log::{debug, error, info}; +use memadvise::{Advice, MemAdviseError}; use snafu::{ResultExt, Snafu}; use tokio::{ io::{AsyncReadExt, AsyncWriteExt}, @@ -143,6 +144,18 @@ pub async fn handle_connection( .context(WriteToStatisticsChannelSnafu)?; let mut buffer = vec![0u8; network_buffer_size]; + + if let Err(err) = memadvise::advise(buffer.as_ptr() as _, buffer.len(), Advice::Sequential) { + // [`MemAdviseError`] does not implement Debug... + let err = match err { + MemAdviseError::NullAddress => "NullAddress", + MemAdviseError::InvalidLength => "InvalidLength", + MemAdviseError::UnalignedAddress => "UnalignedAddress", + MemAdviseError::InvalidRange => "InvalidRange", + }; + error!("Failed to memadvise buffer to kernel, propably having some performance degration: {err}"); + } + // Number bytes left over **on the first bytes of the buffer** from the previous loop iteration let mut leftover_bytes_in_buffer = 0; @@ -236,5 +249,7 @@ pub async fn handle_connection( let _ = tx.send(ip); } + let _ = memadvise::advise(buffer.as_ptr() as _, buffer.len(), Advice::DontNeed); + Ok(()) } From 748e2a97bf9e2cafb4760f7e041ba6ebfbfd30b5 Mon Sep 17 00:00:00 2001 From: Sebastian Bernauer Date: Thu, 30 May 2024 19:00:25 +0200 Subject: [PATCH 2/5] Try 2 --- Cargo.lock | 13 ++++++++++++- Cargo.toml | 1 + breakwater/Cargo.toml | 1 + breakwater/src/server.rs | 11 ++++++++++- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b4871d0..85d35eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -183,6 +183,7 @@ dependencies = [ "log", "memadvise", "number_prefix", + "page_size 0.6.0", "prometheus_exporter", "rstest", "rusttype", @@ -984,7 +985,7 @@ checksum = "aaf6f86f067270b307b65d17080ac0eac2afd247d60f49646db200c9b8680cf4" dependencies = [ "kernel32-sys", "libc", - "page_size", + "page_size 0.4.2", "winapi 0.2.8", ] @@ -1113,6 +1114,16 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "page_size" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "parking_lot" version = "0.12.3" diff --git a/Cargo.toml b/Cargo.toml index 7c63ecf..c4f98d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ log = "0.4" memadvise = "0.1" memchr = "2.7" number_prefix = "0.4" +page_size = "0.6" pixelbomber = "0.6" prometheus_exporter = "0.8" rstest = "0.20" diff --git a/breakwater/Cargo.toml b/breakwater/Cargo.toml index da30c2d..557369b 100644 --- a/breakwater/Cargo.toml +++ b/breakwater/Cargo.toml @@ -22,6 +22,7 @@ env_logger.workspace = true log.workspace = true memadvise.workspace = true number_prefix.workspace = true +page_size.workspace = true prometheus_exporter.workspace = true rusttype.workspace = true serde_json.workspace = true diff --git a/breakwater/src/server.rs b/breakwater/src/server.rs index ef07636..a1f6dae 100644 --- a/breakwater/src/server.rs +++ b/breakwater/src/server.rs @@ -1,3 +1,4 @@ +use std::alloc; use std::collections::hash_map::Entry; use std::collections::HashMap; use std::{cmp::min, net::IpAddr, sync::Arc, time::Duration}; @@ -76,6 +77,10 @@ impl Server { let (connection_dropped_tx, mut connection_dropped_rx) = mpsc::unbounded_channel::(); let connection_dropped_tx = self.max_connections_per_ip.map(|_| connection_dropped_tx); + + let page_size = page_size::get(); + info!("System has a page size of {page_size} bytes"); + loop { let (mut socket, socket_addr) = self .listener @@ -119,6 +124,7 @@ impl Server { ip, fb_for_thread, statistics_tx_for_thread, + page_size, network_buffer_size, connection_dropped_tx_clone, ) @@ -133,6 +139,7 @@ pub async fn handle_connection( ip: IpAddr, fb: Arc, statistics_tx: mpsc::Sender, + page_size: usize, network_buffer_size: usize, connection_dropped_tx: Option>, ) -> Result<(), Error> { @@ -143,7 +150,9 @@ pub async fn handle_connection( .await .context(WriteToStatisticsChannelSnafu)?; - let mut buffer = vec![0u8; network_buffer_size]; + let layout = alloc::Layout::from_size_align(network_buffer_size, page_size).unwrap(); + let ptr = unsafe { alloc::alloc(layout) }; + let buffer = unsafe { std::slice::from_raw_parts_mut(ptr, network_buffer_size) }; if let Err(err) = memadvise::advise(buffer.as_ptr() as _, buffer.len(), Advice::Sequential) { // [`MemAdviseError`] does not implement Debug... From 4621bfd7e3f51b91eae5b6af046f14fbf3d52dc0 Mon Sep 17 00:00:00 2001 From: Sebastian Bernauer Date: Thu, 30 May 2024 19:08:38 +0200 Subject: [PATCH 3/5] changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4768afd..130853c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Added + +- Try to improve performance by calling `madvise` to inform Kernel we are reading sequentially ([#24]) + +[#24]: https://github.com/sbernauer/breakwater/pull/24 + ## [0.14.0] - 2024-05-30 at GPN 22 :) ### Added From 6b42b48399a81899370a3d2ff4941c3852a16ecf Mon Sep 17 00:00:00 2001 From: Sebastian Bernauer Date: Thu, 30 May 2024 19:09:40 +0200 Subject: [PATCH 4/5] change loglevel --- breakwater/src/server.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/breakwater/src/server.rs b/breakwater/src/server.rs index a1f6dae..d723f2f 100644 --- a/breakwater/src/server.rs +++ b/breakwater/src/server.rs @@ -79,7 +79,7 @@ impl Server { let connection_dropped_tx = self.max_connections_per_ip.map(|_| connection_dropped_tx); let page_size = page_size::get(); - info!("System has a page size of {page_size} bytes"); + debug!("System has a page size of {page_size} bytes"); loop { let (mut socket, socket_addr) = self From 3a9e27fb35df6dbadb48ced65c78bab0a08fb388 Mon Sep 17 00:00:00 2001 From: Sebastian Bernauer Date: Thu, 30 May 2024 19:15:36 +0200 Subject: [PATCH 5/5] fix tests --- breakwater/src/tests.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/breakwater/src/tests.rs b/breakwater/src/tests.rs index dc49c92..42fc8dd 100644 --- a/breakwater/src/tests.rs +++ b/breakwater/src/tests.rs @@ -59,6 +59,7 @@ async fn test_correct_responses_to_general_commands( ip, fb, statistics_channel.0, + page_size::get(), DEFAULT_NETWORK_BUFFER_SIZE, None, ) @@ -126,6 +127,7 @@ async fn test_setting_pixel( fb, statistics_channel.0, DEFAULT_NETWORK_BUFFER_SIZE, + page_size::get(), None, ) .await @@ -154,6 +156,7 @@ async fn test_safe( fb.clone(), statistics_channel.0, DEFAULT_NETWORK_BUFFER_SIZE, + page_size::get(), None, ) .await @@ -228,6 +231,7 @@ async fn test_drawing_rect( Arc::clone(&fb), statistics_channel.0.clone(), DEFAULT_NETWORK_BUFFER_SIZE, + page_size::get(), None, ) .await @@ -242,6 +246,7 @@ async fn test_drawing_rect( Arc::clone(&fb), statistics_channel.0.clone(), DEFAULT_NETWORK_BUFFER_SIZE, + page_size::get(), None, ) .await @@ -256,6 +261,7 @@ async fn test_drawing_rect( Arc::clone(&fb), statistics_channel.0.clone(), DEFAULT_NETWORK_BUFFER_SIZE, + page_size::get(), None, ) .await @@ -270,6 +276,7 @@ async fn test_drawing_rect( Arc::clone(&fb), statistics_channel.0.clone(), DEFAULT_NETWORK_BUFFER_SIZE, + page_size::get(), None, ) .await