Skip to content

Commit

Permalink
Merge pull request #2623 from subspace/fix-farming-performance-windows
Browse files Browse the repository at this point in the history
Fix farming performance windows
  • Loading branch information
nazar-pc authored Mar 18, 2024
2 parents f51e1a0 + 21194a8 commit 5d1f276
Show file tree
Hide file tree
Showing 5 changed files with 216 additions and 91 deletions.
16 changes: 6 additions & 10 deletions crates/subspace-farmer-components/src/file_ext.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! File extension trait

use std::fs::{File, OpenOptions};
use std::io::{Result, Seek, SeekFrom};
use std::io::Result;

/// Extension convenience trait that allows setting some file opening options in cross-platform way
pub trait OpenOptionsExt {
Expand Down Expand Up @@ -79,10 +79,10 @@ impl OpenOptionsExt for OpenOptions {
/// and doing cross-platform exact reads/writes
pub trait FileExt {
/// Get file size
fn size(&mut self) -> Result<u64>;
fn size(&self) -> Result<u64>;

/// Make sure file has specified number of bytes allocated for it
fn preallocate(&mut self, len: u64) -> Result<()>;
fn preallocate(&self, len: u64) -> Result<()>;

/// Advise OS/file system that file will use random access and read-ahead behavior is
/// undesirable, on Windows this can only be set when file is opened, see [`OpenOptionsExt`]
Expand All @@ -100,15 +100,11 @@ pub trait FileExt {
}

impl FileExt for File {
fn size(&mut self) -> Result<u64> {
self.seek(SeekFrom::End(0))
fn size(&self) -> Result<u64> {
Ok(self.metadata()?.len())
}

fn preallocate(&mut self, len: u64) -> Result<()> {
// TODO: Hack due to bugs on Windows: https://github.com/al8n/fs4-rs/issues/13
if self.size()? == len {
return Ok(());
}
fn preallocate(&self, len: u64) -> Result<()> {
fs2::FileExt::allocate(self, len)
}

Expand Down
39 changes: 15 additions & 24 deletions crates/subspace-farmer/src/single_disk_farm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1220,7 +1220,7 @@ impl SingleDiskFarm {

let metadata_file_path = directory.join(Self::METADATA_FILE);
#[cfg(not(windows))]
let mut metadata_file = OpenOptions::new()
let metadata_file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
Expand All @@ -1231,7 +1231,7 @@ impl SingleDiskFarm {
metadata_file.advise_random_access()?;

#[cfg(windows)]
let mut metadata_file = UnbufferedIoFileWindows::open(&metadata_file_path)?;
let metadata_file = UnbufferedIoFileWindows::open(&metadata_file_path)?;

let metadata_size = metadata_file.size()?;
let expected_metadata_size =
Expand Down Expand Up @@ -1323,7 +1323,7 @@ impl SingleDiskFarm {
};

#[cfg(not(windows))]
let mut plot_file = OpenOptions::new()
let plot_file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
Expand All @@ -1334,7 +1334,7 @@ impl SingleDiskFarm {
plot_file.advise_random_access()?;

#[cfg(windows)]
let mut plot_file = UnbufferedIoFileWindows::open(&directory.join(Self::PLOT_FILE))?;
let plot_file = UnbufferedIoFileWindows::open(&directory.join(Self::PLOT_FILE))?;

if plot_file.size()? != plot_file_size {
// Allocating the whole file (`set_len` below can create a sparse file, which will cause
Expand All @@ -1344,12 +1344,6 @@ impl SingleDiskFarm {
.map_err(SingleDiskFarmError::CantPreallocatePlotFile)?;
// Truncating file (if necessary)
plot_file.set_len(plot_file_size)?;

// TODO: Hack due to Windows bugs:
// https://learn.microsoft.com/en-us/answers/questions/1608540/getfileinformationbyhandle-followed-by-read-with-f
if cfg!(windows) {
warn!("Farm was resized, farmer restart is needed for optimal performance!")
}
}

let plot_file = Arc::new(plot_file);
Expand Down Expand Up @@ -1399,13 +1393,12 @@ impl SingleDiskFarm {
directory: &Path,
) -> io::Result<Vec<SectorMetadataChecksummed>> {
#[cfg(not(windows))]
let mut metadata_file = OpenOptions::new()
let metadata_file = OpenOptions::new()
.read(true)
.open(directory.join(Self::METADATA_FILE))?;

#[cfg(windows)]
let mut metadata_file =
UnbufferedIoFileWindows::open(&directory.join(Self::METADATA_FILE))?;
let metadata_file = UnbufferedIoFileWindows::open(&directory.join(Self::METADATA_FILE))?;

let metadata_size = metadata_file.size()?;
let sector_metadata_size = SectorMetadataChecksummed::encoded_size();
Expand Down Expand Up @@ -1671,7 +1664,7 @@ impl SingleDiskFarm {
let (metadata_file, mut metadata_header) = {
info!(path = %metadata_file_path.display(), "Checking metadata file");

let mut metadata_file = match OpenOptions::new()
let metadata_file = match OpenOptions::new()
.read(true)
.write(true)
.open(&metadata_file_path)
Expand Down Expand Up @@ -1772,7 +1765,7 @@ impl SingleDiskFarm {
let plot_file_path = directory.join(Self::PLOT_FILE);
info!(path = %plot_file_path.display(), "Checking plot file");

let mut plot_file = match OpenOptions::new()
let plot_file = match OpenOptions::new()
.read(true)
.write(true)
.open(&plot_file_path)
Expand Down Expand Up @@ -2048,7 +2041,7 @@ impl SingleDiskFarm {
let file = directory.join(DiskPieceCache::FILE_NAME);
info!(path = %file.display(), "Checking cache file");

let mut cache_file = match OpenOptions::new().read(true).write(true).open(&file) {
let cache_file = match OpenOptions::new().read(true).write(true).open(&file) {
Ok(plot_file) => plot_file,
Err(error) => {
return Err(if error.kind() == io::ErrorKind::NotFound {
Expand Down Expand Up @@ -2211,17 +2204,15 @@ where
// A lot simplified version of concurrent chunks
{
let start = Instant::now();
(0..Record::NUM_S_BUCKETS)
.into_par_iter()
.try_for_each(|_| {
let offset = thread_rng().gen_range(0_usize..sector_size / Scalar::FULL_BYTES)
* Scalar::FULL_BYTES;
farming_plot.read_at(&mut [0; Scalar::FULL_BYTES], offset as u64)
})?;
(0..Record::NUM_CHUNKS).into_par_iter().try_for_each(|_| {
let offset = thread_rng().gen_range(0_usize..sector_size / Scalar::FULL_BYTES)
* Scalar::FULL_BYTES;
farming_plot.read_at(&mut [0; Scalar::FULL_BYTES], offset as u64)
})?;
let elapsed = start.elapsed();

if elapsed >= INTERNAL_BENCHMARK_READ_TIMEOUT {
debug!(
info!(
?elapsed,
"Proving method with chunks reading is too slow, using whole sector"
);
Expand Down
4 changes: 2 additions & 2 deletions crates/subspace-farmer/src/single_disk_farm/piece_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl DiskPieceCache {
}

#[cfg(not(windows))]
let mut file = OpenOptions::new()
let file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
Expand All @@ -84,7 +84,7 @@ impl DiskPieceCache {
file.advise_random_access()?;

#[cfg(windows)]
let mut file = UnbufferedIoFileWindows::open(&directory.join(Self::FILE_NAME))?;
let file = UnbufferedIoFileWindows::open(&directory.join(Self::FILE_NAME))?;

let expected_size = u64::from(Self::element_size()) * u64::from(capacity);
// Align plot file size for disk sector size
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ fn basic() {

let tempdir = tempdir().unwrap();
#[cfg(not(windows))]
let mut file = OpenOptions::new()
let file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
Expand All @@ -40,7 +40,7 @@ fn basic() {
.unwrap();

#[cfg(windows)]
let mut file = UnbufferedIoFileWindows::open(&tempdir.path().join("plot.bin")).unwrap();
let file = UnbufferedIoFileWindows::open(&tempdir.path().join("plot.bin")).unwrap();

// Align plot file size for disk sector size
file.preallocate(
Expand Down
Loading

0 comments on commit 5d1f276

Please sign in to comment.