Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using splice system call for even better performance #12

Open
janflyborg opened this issue Nov 20, 2017 · 4 comments
Open

Using splice system call for even better performance #12

janflyborg opened this issue Nov 20, 2017 · 4 comments

Comments

@janflyborg
Copy link

HAProxy (and probably also Redis) is using the system call splice in Linux (http://man7.org/linux/man-pages/man2/splice.2.html) in order to copy data from one file descriptor to another.

This means that it efficiently implements proxying functionality, since it does not have to copy data from the kernel to user space and then back to the kernel.

The pattern of letting the callback evio.Events.Data always perform a copy in user space, will always be somewhat slower than what HAProxy can achieve, so is this something you have thought about for evio?

@diegobernardes
Copy link

diegobernardes commented Dec 1, 2017

The proposal to add splice at the std lib was accepted: golang/go#10948. There is also a prototype of it: golang/go@master...philhofer:net-splice

Adding splice to evio would be very nice too, @janflyborg is right, you can't really compete with HAProxy without this.

@tidwall
Copy link
Owner

tidwall commented Dec 1, 2017

@janflyborg

Thanks for the suggestion. It's not something I've put much thought into yet (but I should). I've been mostly focused on data translations at the protocol layer, such as gRPC to Redis and fan-in packet pipelining. Stuff that needs to be done in user space.

I could be wrong but I don't think Redis uses splice. Likely because data must be read off the wire into user space to be parsed. Right now I'm seeing equivalent performance of evio and Redis.

As for direct byte-to-byte proxies, I absolutely see how using splice would benefit performance. I'm always happy to leave any operation that I can up to the kernel.
Not sure how I would implement it yet in the evio API... 🤔 I'll figure something out.

@diegobernardes

Thanks for the very helpful links. It appears that Go has a syscall.Splice operation that I can use. That's a plus!

@janflyborg
Copy link
Author

janflyborg commented Dec 1, 2017

Thanks for the answers @diegobernardes and @tidwall. That sounds really good. Evio is just what I have been looking for and even if I have not used it yet, it seems like a perfect fit for some of the use cases I encounter from day to day.
Zero-copy is impossible to achieve when you have to transform or inspect the data, so you are probably correct that Redis does not use splice.

I have looked at philhofer's patch for the stdlib and since it is deeply tied to the rest of the library, I'm not sure if it will help you here, but the syscall is (as you said) at least available.

@ghost
Copy link

ghost commented Sep 9, 2019

any development with this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants