Skip to content

Commit

Permalink
Create single Rayon threadpool and use for YIQ ops
Browse files Browse the repository at this point in the history
  • Loading branch information
valadaptive committed Jan 12, 2025
1 parent a0a6927 commit 6fa374e
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 170 deletions.
1 change: 1 addition & 0 deletions crates/ntscrs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub mod ntsc;
mod random;
pub mod settings;
mod shift;
pub mod thread_pool;
pub mod yiq_fielding;

#[macro_use]
Expand Down
29 changes: 2 additions & 27 deletions crates/ntscrs/src/ntsc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::{
filter::TransferFunction,
random::{Geometric, Seeder},
shift::{shift_row, shift_row_to, BoundaryHandling},
thread_pool::with_thread_pool,
yiq_fielding::{BlitInfo, PixelFormat, YiqField, YiqOwned, YiqView},
};

Expand Down Expand Up @@ -1368,33 +1369,7 @@ impl NtscEffect {

/// Apply the effect to YIQ image data.
pub fn apply_effect_to_yiq(&self, yiq: &mut YiqView, frame_num: usize) {
#[cfg(not(target_arch = "wasm32"))]
{
use std::sync::OnceLock;
static NUM_THREADS: OnceLock<Option<usize>> = OnceLock::new();
// On Windows debug builds, the stack overflows with the default stack size
let mut pool = rayon::ThreadPoolBuilder::new().stack_size(2 * 1024 * 1024);

// Use physical core count instead of logical core count. Hyperthreading seems to be ~20-25% slower, at least on
// a Ryzen 7 7700X.
if let Some(num_threads) = *NUM_THREADS.get_or_init(|| {
if std::env::var("RAYON_NUM_THREADS").is_ok() {
return None;
}
Some(num_cpus::get_physical())
}) {
pool = pool.num_threads(num_threads);
}

let pool = pool.build().unwrap();
pool.scope(|_| self.apply_effect_to_all_fields(yiq, frame_num));
}
#[cfg(target_arch = "wasm32")]
{
// wasm-bindgen-rayon doesn't support custom thread pools
// https://github.com/RReverser/wasm-bindgen-rayon/issues/18
self.apply_effect_to_all_fields(yiq, frame_num);
}
with_thread_pool(|| self.apply_effect_to_all_fields(yiq, frame_num));
}

/// Apply the effect to a buffer which contains pixels in the given format.
Expand Down
28 changes: 28 additions & 0 deletions crates/ntscrs/src/thread_pool.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
pub fn with_thread_pool<T: Send>(op: impl (FnOnce() -> T) + Send + Sync) -> T {
#[cfg(not(target_arch = "wasm32"))]
{
use std::sync::OnceLock;
static POOL: OnceLock<rayon::ThreadPool> = OnceLock::new();

let pool = POOL.get_or_init(|| {
// On Windows debug builds, the stack overflows with the default stack size
let mut pool = rayon::ThreadPoolBuilder::new().stack_size(2 * 1024 * 1024);

// Use physical core count instead of logical core count. Hyperthreading seems to be ~20-25% slower, at least on
// a Ryzen 7 7700X.
if std::env::var("RAYON_NUM_THREADS").is_err() {
pool = pool.num_threads(num_cpus::get_physical());
}

pool.build().unwrap()
});

pool.scope(|_| op())
}
#[cfg(target_arch = "wasm32")]
{
// wasm-bindgen-rayon doesn't support custom thread pools
// https://github.com/RReverser/wasm-bindgen-rayon/issues/18
op()
}
}
Loading

0 comments on commit 6fa374e

Please sign in to comment.