-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Implement initializer() for FileDesc #53981
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @shepmaster (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
in order to avoid constantly zeroing memory when it's not needed.
r? @sfackler from the git history I think this could be interesting to you. |
@bors r+ Thanks! |
📌 Commit 28745a6 has been approved by |
Implement initializer() for FileDesc Here was my initial issue: ```rust use std::process::{Command}; fn main() { let output = Command::new("curl").arg("-s").arg("http://ovh.net/files/100Mio.dat").output(); println!("{:?}", output.unwrap().stdout.len()); } ``` ``` ~/stuff ❯❯❯ time ./dwl 104857600 ./dwl 16.22s user 1.80s system 23% cpu 1:15.24 total ``` ```rust use std::process::{Command, Stdio}; fn main() { let child = Command::new("curl").arg("-s").arg("http://ovh.net/files/100Mio.dat").stdout(Stdio::piped()).spawn(); let output = child.unwrap().wait_with_output().unwrap(); println!("{:?}", output.stdout.len()); } ``` ``` ~/stuff ❯❯❯ time ./dwl2 104857600 ./dwl2 0.64s user 2.18s system 5% cpu 53.072 total ``` As you can see the first version is spending much more time in userland and also uses more cpu. With the help of @programble, @talchas and @habnabit on the rust IRC, we discovered that the slow version uses two pipes, one for `stdin` and one for `stderr` and in that case it polls when going through [this function](https://github.com/rust-lang/rust/blob/master/src/libstd/sys/unix/pipe.rs#L82). The polling calls `read_to_end` on the pipes repetitively and this results in zeroing its internal buffer each time. To avoid this zeroing, `FileDesc` needs to implement `initializer`. We see no reason why it [wouldn't work with uninitialized memory](https://doc.rust-lang.org/1.26.1/src/std/io/mod.rs.html#534) so this PR fixes that. Here is some tracing of the slow program: ![image](https://user-images.githubusercontent.com/147585/45133180-ed8a2d80-b161-11e8-9ec7-09979ec96145.png) versus the fast program: ![image](https://user-images.githubusercontent.com/147585/45133216-0c88bf80-b162-11e8-908e-ff81d59239fb.png) I have not tested the change yet but will try to build it tomorrow.
Rollup of 11 pull requests Successful merges: - #51366 (stabilize #[panic_handler]) - #53162 (rustdoc: collect trait impls as an early pass) - #53932 ([NLL] Remove base_place) - #53942 (Rewrite `precompute_borrows_out_of_scope` for fewer hash table lookups.) - #53973 (Have rust-lldb look for the rust-enabled lldb) - #53981 (Implement initializer() for FileDesc) - #53987 (rustbuild: allow configuring llvm version suffix) - #53993 (rustc_resolve: don't record uniform_paths canaries as reexports.) - #54007 (crates that provide a `panic_handler` are exempt from the `unused_extern_crates` lint) - #54040 (update books for next release) - #54050 (Update `petgraph` dependency to 0.4.13 to fix build with nightly) Failed merges: r? @ghost
Implement initializer() for FileDesc Here was my initial issue: ```rust use std::process::{Command}; fn main() { let output = Command::new("curl").arg("-s").arg("http://ovh.net/files/100Mio.dat").output(); println!("{:?}", output.unwrap().stdout.len()); } ``` ``` ~/stuff ❯❯❯ time ./dwl 104857600 ./dwl 16.22s user 1.80s system 23% cpu 1:15.24 total ``` ```rust use std::process::{Command, Stdio}; fn main() { let child = Command::new("curl").arg("-s").arg("http://ovh.net/files/100Mio.dat").stdout(Stdio::piped()).spawn(); let output = child.unwrap().wait_with_output().unwrap(); println!("{:?}", output.stdout.len()); } ``` ``` ~/stuff ❯❯❯ time ./dwl2 104857600 ./dwl2 0.64s user 2.18s system 5% cpu 53.072 total ``` As you can see the first version is spending much more time in userland and also uses more cpu. With the help of @programble, @talchas and @habnabit on the rust IRC, we discovered that the slow version uses two pipes, one for `stdin` and one for `stderr` and in that case it polls when going through [this function](https://github.com/rust-lang/rust/blob/master/src/libstd/sys/unix/pipe.rs#L82). The polling calls `read_to_end` on the pipes repetitively and this results in zeroing its internal buffer each time. To avoid this zeroing, `FileDesc` needs to implement `initializer`. We see no reason why it [wouldn't work with uninitialized memory](https://doc.rust-lang.org/1.26.1/src/std/io/mod.rs.html#534) so this PR fixes that. Here is some tracing of the slow program: ![image](https://user-images.githubusercontent.com/147585/45133180-ed8a2d80-b161-11e8-9ec7-09979ec96145.png) versus the fast program: ![image](https://user-images.githubusercontent.com/147585/45133216-0c88bf80-b162-11e8-908e-ff81d59239fb.png) I have not tested the change yet but will try to build it tomorrow.
Rollup of 10 pull requests Successful merges: - #53315 (use `NonZeroU32` in `newtype_index!`macro, change syntax) - #53932 ([NLL] Remove base_place) - #53942 (Rewrite `precompute_borrows_out_of_scope` for fewer hash table lookups.) - #53973 (Have rust-lldb look for the rust-enabled lldb) - #53981 (Implement initializer() for FileDesc) - #53987 (rustbuild: allow configuring llvm version suffix) - #53993 (rustc_resolve: don't record uniform_paths canaries as reexports.) - #54007 (crates that provide a `panic_handler` are exempt from the `unused_extern_crates` lint) - #54040 (update books for next release) - #54050 (Update `petgraph` dependency to 0.4.13 to fix build with nightly)
Here was my initial issue:
As you can see the first version is spending much more time in userland and also uses more cpu. I discovered that the slow version uses two pipes, one for
stdin
and one forstderr
and in that case it polls when going through this function. The polling callsread_to_end
on the pipes repetitively and this results in zeroing its internal buffer each time. To avoid this zeroing,FileDesc
needs to implementinitializer
. I see no reason why it wouldn't work with uninitialized memory so this PR fixes that.Here is some tracing of the slow program:
versus the fast program:
I have not tested the change yet but will try to build it tomorrow.