Skip to content

Commit

Permalink
Use memory-mapped I/O on Windows for better random access performance
Browse files Browse the repository at this point in the history
  • Loading branch information
nazar-pc committed Oct 5, 2023
1 parent 9679c3d commit 7294cb5
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions crates/subspace-farmer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,6 @@ zeroize = "1.6.0"
# The only triple tested and confirmed as working in `jemallocator` crate is `x86_64-unknown-linux-gnu`
[target.'cfg(all(target_arch = "x86_64", target_vendor = "unknown", target_os = "linux", target_env = "gnu"))'.dependencies]
jemallocator = "0.5.0"

[target.'cfg(windows)'.dependencies]
memmap2 = "0.9.0"
32 changes: 32 additions & 0 deletions crates/subspace-farmer/src/single_disk_farm/farming.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use crate::node_client::NodeClient;
use crate::single_disk_farm::Handlers;
use futures::channel::mpsc;
use futures::StreamExt;
#[cfg(windows)]
use memmap2::{Mmap, MmapOptions};
use parking_lot::{Mutex, RwLock};
use rayon::prelude::*;
use rayon::{ThreadPoolBuildError, ThreadPoolBuilder};
Expand All @@ -27,6 +29,16 @@ use tracing::{debug, error, trace, warn};
/// many solutions.
const SOLUTIONS_LIMIT: usize = 1;

#[cfg(windows)]
struct MmapWrapper(Mmap);

#[cfg(windows)]
impl ReadAt for MmapWrapper {
fn read_at(&self, buf: &mut [u8], offset: usize) -> io::Result<()> {
self.0.read_at(buf, offset)
}
}

/// Errors that happen during farming
#[derive(Debug, Error)]
pub enum FarmingError {
Expand Down Expand Up @@ -136,7 +148,27 @@ where
.into_par_iter()
.zip(&*sectors_metadata)
.filter_map(|(sector_index, sector_metadata)| {
#[cfg(not(windows))]
let sector = plot_file.offset(sector_index * sector_size);
// On Windows random read is horrible in terms of performance, memory-mapped I/O
// helps
// TODO: Remove this once https://internals.rust-lang.org/t/introduce-write-all-at-read-exact-at-on-windows/19649
// or similar exists in standard library
#[cfg(windows)]
let maybe_sector = unsafe {
MmapOptions::new()
.offset(sector_index as u64 * sector_size as u64)
.len(sector_size)
.map(plot_file)
};
#[cfg(windows)]
let sector = match maybe_sector {
Ok(sector) => MmapWrapper(sector),
Err(error) => {
warn!(%error, %sector_index, "Failed to memory-map sector");
return None;
}
};

let sector_index = sector_index as u16;
if maybe_sector_being_modified == Some(sector_index) {
Expand Down

0 comments on commit 7294cb5

Please sign in to comment.