shadow icon indicating copy to clipboard operation
shadow copied to clipboard

Unnecessary buffer initialization in ByteQueue::push

Open sporksmith opened this issue 3 years ago • 2 comments

ByteQueue::push uses the standard library's Read::read_to_end. To avoid making uninitialized data available to the Read implementation, it currently initializes the buffer before passing it to read.

It looks like there's currently an internal / nightly API for marking a reader as promising not to read the buffer it's passed, in which case the initialization will be skipped.

  • https://doc.rust-lang.org/src/std/io/mod.rs.html#391
  • https://doc.rust-lang.org/std/io/trait.Read.html#method.initializer

In the meantime we may want to replace our usage of read_to_end with something that doesn't pre-initialize.

Example from a perf report, in a benchmark reading and writing 64 KB buffers via a pipe:

-   18.48%     0.26%             4  worker-0  shadow  [.] shadow_rs::utility::byte_queue::ByteQueue::push
   - 18.22% shadow_rs::utility::byte_queue::ByteQueue::push
      - 16.16% <std::io::Take<T> as std::io::Read>::read_to_end
         + 8.80% <shadow_rs::host::memory_manager::MemoryReaderCursor as std::io::Read>::read
           6.47% __memset_avx2_erms 

We spend almost as much time zeroing the buffer (__memset_avx2_erms) as copying the data (read)

sporksmith avatar Sep 15 '21 15:09 sporksmith

Btw it looks like the initializer method is unlikely to be stabilized. It's been superseded by the (merged, but unimplemented) ReadBuf RFC

sporksmith avatar Sep 15 '21 16:09 sporksmith

We decided this doesn't really fit in any milestone currently, and we are waiting for improvements in the Rust API before we can make progress.

robgjansen avatar Oct 19 '21 17:10 robgjansen