Snowiiii / Pumpkin

Empowering everyone to host fast and efficient Minecraft servers.
MIT License
532 stars 25 forks source link

We need player write buf to cache packet bytes #25

Open Bruce0203 opened 1 month ago

Bruce0203 commented 1 month ago

TcpStream::write_all is quite slow, possibly due to syscall overhead. For better performance, we should implement a write buffer for caching and create a custom write interest registry to avoid the syscall overhead from mio registration.

Snowiiii commented 1 month ago

Hey, I will definitely look into this. thanks

Snowiiii commented 1 month ago

Hey @Bruce0203, Your right TcpStream::write_all is actually slow and we probably should use an write/flush method, But im unsure when we should flush, Im also unsure what do you mean with creating custom interest registry ?. Currently we creating a Readable and Writable interest registry when we get a new connection.

Bruce0203 commented 1 month ago

Hey @Bruce0203, Your right TcpStream::write_all is actually slow and we probably should use an write/flush method, But im unsure when we should flush, Im also unsure what do you mean with creating custom interest registry ?. Currently we creating a Readable and Writable interest registry when we get a new connection.

Um... The phrase 'create custom interest registry' was a bit unclear. Let me clarify it. When we write a packet, registering interest each time is quite expensive. It takes about 200 to 300 nanoseconds due to the syscall overhead. My idea was to create a custom write interest registry using something like Vec\<mio::Token> This way, when we write a packet, we can register interest by storing it into Vec\<mio::Token> instead of registering it with a syscall.

Snowiiii commented 3 weeks ago

So i learned more about networking and now know what problem we have here. We could use io_uring to fix this issue the problem is that this is only a linux thing. As far as i understood kqueue is the equivalent for this on FreeBSD and macOS.

There is tokio-uring but it has its own runtime and we would to have to write an own wrapper around that to support other OS's

Here is what i also found:

lukas0008 commented 2 weeks ago

Imho using uring would be kind of overkill (especially since its so difficult to implement), using something like a std::ioBufReader and std::io::BufWriter would be enough to give a dramatic speed up.

Note for implementation: remember to call BufWriter::flush on an interval, since otherwise the client is likely to be stuck in the handshake/config stage (since not many packets are sent at that time).