neondatabase / tokio-epoll-uring

Use io_uring from vanilla tokio.
36 stars 4 forks source link

Avoid overhead of constructing debug messages that are not printed #54

Closed hlinnaka closed 2 weeks ago

hlinnaka commented 1 month ago

I noticed that the neon pageserver unit tests were taking much longer with tokio-epoll-uring than with std:fs. It was because many of the tests used tokio::time:pause(), and then did a call to tokio::time::timeout() with a long 1h timeout. With tokio-epoll-uring, the loop in poller_impl_impl() woke up 36000 times, i.e. once for every 100 ms of virtual time, before the timeout was reached. The significance of that varies greatly depend on debug vs release build; it's particularly bad when I use nightly compiler with cranelift codegen backend.

It would be better to avoid the wakeups every 100 ms altogether, if the debug-level events are not enabled, but it scares me to have such different behavior depending on a debug-level. It sounds like a recipe for very hard-to-debug bugs. Or perhaps the debug dumping could be just removed altogether? That would be good for saving battery life when the system is idle.

hlinnaka commented 1 month ago

Not suitable for including as a test, but this can be used to demo the effect:

diff --git a/tokio-epoll-uring/Cargo.toml b/tokio-epoll-uring/Cargo.toml
index 07e12a8..7b3f9fa 100644
--- a/tokio-epoll-uring/Cargo.toml
+++ b/tokio-epoll-uring/Cargo.toml
@@ -22,3 +22,4 @@ tempfile = "3.6.0"
 tracing-subscriber = "*"
 os_pipe = "1.1.4"
 assert-panic = "1.0.1"
+tokio = { version = "1.29.1", features = [ "test-util" ] }
diff --git a/tokio-epoll-uring/src/system/tests.rs b/tokio-epoll-uring/src/system/tests.rs
index 0168ef1..f8e994a 100644
--- a/tokio-epoll-uring/src/system/tests.rs
+++ b/tokio-epoll-uring/src/system/tests.rs
@@ -298,3 +298,12 @@ async fn test_write() {

     drop(fd);
 }
+
+
+#[tokio::test]
+async fn test_nothing() {
+    let _system = System::launch().await.unwrap();
+
+    tokio::time::pause();
+    let _ = tokio::time::timeout(Duration::from_secs(360000), std::future::pending::<()>()).await;
+}

The test finishes much quicker with this PR.