[pbs-devel] [PATCH v2 pxar 2/2] decoder: aio: improve performance of async file reads

Fabian Grünbichler f.gruenbichler at proxmox.com
Mon Jul 31 16:57:17 CEST 2023


On July 31, 2023 3:34 pm, Max Carrara wrote:
> In order to bring `aio::Decoder` on par with its `sync` counterpart
> as well as `sync::Accessor` and `aio::Accessor`, its input is now
> buffered.
> 
> As the `tokio` docs mention themselves [0], it can be really
> inefficient to directly work with an (unbuffered) `AsyncRead`
> instance.
> 
> The other aforementioned types already buffer their reads in one way
> or another, so wrapping the input reader in `tokio::io::BufReader`
> results in a substantial performance gain. [1]
> 
> `tokio/io-util` is added as dependency in order to use
> `tokio::io::BufReader`.
> 
> [0]: https://docs.rs/tokio/1.29.1/tokio/io/struct.BufReader.html
> [1]: Tested via examples/compare-read.rs on a large (13GB) pxar archive
> 
> Before:
>> PXAR Read Performance Comparison
>> Running in mode: release
>>
>> First pass:
>> With aio::Decoder:   Ok(()) (elapsed: 20.532270177s)
>> With sync::Decoder:  Ok(()) (elapsed: 3.498566141s)
>> With aio::Accessor:  Ok(()) (elapsed: 3.978160609s)
>> With sync::Accessor: Ok(()) (elapsed: 3.885640895s)
>>
>> Second pass:
>> With aio::Decoder:   Ok(()) (elapsed: 18.648986266s)
>> With sync::Decoder:  Ok(()) (elapsed: 3.617167922s)
>> With aio::Accessor:  Ok(()) (elapsed: 4.083678211s)
>> With sync::Accessor: Ok(()) (elapsed: 4.103763507s)
> 
> After:
>> PXAR Read Performance Comparison
>> Running in mode: release
>>
>> First pass:
>> With aio::Decoder:   Ok(()) (elapsed: 9.546522171s)
>> With sync::Decoder:  Ok(()) (elapsed: 3.535062119s)
>> With aio::Accessor:  Ok(()) (elapsed: 3.926439101s)
>> With sync::Accessor: Ok(()) (elapsed: 3.905232916s)
>>
>> Second pass:
>> With aio::Decoder:   Ok(()) (elapsed: 10.633561678s)
>> With sync::Decoder:  Ok(()) (elapsed: 3.528989778s)
>> With aio::Accessor:  Ok(()) (elapsed: 3.831093917s)
>> With sync::Accessor: Ok(()) (elapsed: 3.848684845s)

this does look good to me in general, do you have more details about
your test pxar file?

because for me with a big archive with lots of hardlinks (POM-created
mirror):

buffered:
Time (mean ± σ):     17.360 s ±  0.769 s    [User: 2.460 s, System: 14.345 s]
  Range (min … max):   16.004 s … 18.225 s    10 runs

stock:
Time (mean ± σ):     20.512 s ±  1.248 s    [User: 3.158 s, System: 16.510 s]
  Range (min … max):   19.045 s … 22.176 s    10 runs

Summary
  buffered ran
    1.18 ± 0.09 times faster than stock

and for another even bigger (~40G) archive consisting of a PBS .chunks
dir:

buffered:
Time (mean ± σ):     138.329 s ±  3.627 s    [User: 19.407 s, System: 114.824 s]
  Range (min … max):   134.266 s … 146.754 s    10 runs

stock:
  Time (mean ± σ):     179.822 s ±  3.679 s    [User: 26.894 s, System: 144.526 s]
  Range (min … max):   173.166 s … 186.505 s    10 runs

Summary
  buffered ran
    1.30 ± 0.04 times faster than stock

which, while an obvious improvement, is far from your almost 2x speedup
;)

> 
> Signed-off-by: Max Carrara <m.carrara at proxmox.com>
> ---
>  Changes v1 --> v2:
>   * Include addition of `tokio/io-util` as dependency
>   * Use new examples/compare-read.rs instead of old custom tool to
>     measure performance impact
>   * Use default buffer size (8K) instead of 16K
>     (I wasn't able to reproduce the performance gains, so ...)
> 
>  Cargo.toml         |  2 +-
>  src/decoder/aio.rs | 10 +++++++---
>  2 files changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/Cargo.toml b/Cargo.toml
> index 8669e30..08c0973 100644
> --- a/Cargo.toml
> +++ b/Cargo.toml
> @@ -63,7 +63,7 @@ libc = "0.2"
> 
>  [features]
>  default = [ "tokio-io" ]
> -tokio-io = [ "tokio" ]
> +tokio-io = [ "tokio", "tokio/io-util" ]
>  tokio-fs = [ "tokio-io", "tokio/fs" ]
> 
>  full = [ "tokio-fs"]
> diff --git a/src/decoder/aio.rs b/src/decoder/aio.rs
> index 200dd3d..7cb9c12 100644
> --- a/src/decoder/aio.rs
> +++ b/src/decoder/aio.rs
> @@ -79,14 +79,18 @@ mod tok {
>      use std::pin::Pin;
>      use std::task::{Context, Poll};
> 
> -    /// Read adapter for `futures::io::AsyncRead`
> +    use tokio::io::AsyncRead;
> +
> +    /// Read adapter for `tokio::io::AsyncRead`
>      pub struct TokioReader<T> {
> -        inner: T,
> +        inner: tokio::io::BufReader<T>,
>      }
> 
>      impl<T: tokio::io::AsyncRead> TokioReader<T> {
>          pub fn new(inner: T) -> Self {
> -            Self { inner }
> +            Self {
> +                inner: tokio::io::BufReader::new(inner),
> +            }
>          }
>      }
> 
> --
> 2.39.2
> 
> 
> 
> _______________________________________________
> pbs-devel mailing list
> pbs-devel at lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
> 
> 
> 





More information about the pbs-devel mailing list