rtiow: add core affinity to each render thread.
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Bill Thiede 2019-10-21 10:51:33 -07:00
parent af6cda7349
commit 27ca936264
3 changed files with 50 additions and 15 deletions

13
rtiow/Cargo.lock generated
View File

@ -384,6 +384,17 @@ dependencies = [
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "core_affinity"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cpuprofiler"
version = "0.0.3"
@ -1604,6 +1615,7 @@ dependencies = [
"actix-web 0.7.18 (registry+https://github.com/rust-lang/crates.io-index)",
"askama 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"core_affinity 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
"cpuprofiler 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"criterion 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2458,6 +2470,7 @@ dependencies = [
"checksum cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1465f8134efa296b4c19db34d909637cb2bf0f7aaf21299e23e18fa29ac557cf"
"checksum core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "286e0b41c3a20da26536c6000a280585d519fd07b3956b43aed8a79e9edce980"
"checksum core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "716c271e8613ace48344f723b60b900a93150271e5be206212d052bbc0883efa"
"checksum core_affinity 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6d162c6e463c31dbf78fefa99d042156c1c74d404e299cfe3df2923cb857595b"
"checksum cpuprofiler 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "33f07976bb6821459632d7a18d97ccca005cb5c552f251f822c7c1781c1d7035"
"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
"checksum crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e91d5240c6975ef33aeb5f148f35275c25eda8e8a5f95abe421978b05b8bf192"

View File

@ -12,6 +12,7 @@ name = "spheres"
actix-web = "0.7.8"
askama = "0.7.1"
chrono = "*"
core_affinity = "0.5"
cpuprofiler = { version = "0.0.3", optional = true }
image = "0.19.0"
lazy_static = "1.1.0"

View File

@ -14,6 +14,7 @@ use std::sync::Mutex;
use std::thread;
use std::time;
use core_affinity;
#[cfg(feature = "prom")]
use lazy_static::lazy_static;
use num_cpus;
@ -461,22 +462,36 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i
let scene = Arc::new(scene);
let pixel_req_rx = Arc::new(Mutex::new(pixel_req_rx));
info!("Creating {} render threads", num_threads);
info!("Adaptive subsampling: {:?}", scene.adaptive_subsampling);
for i in 0..num_threads {
let s = sync::Arc::clone(&scene);
let pixel_req_rx = pixel_req_rx.clone();
let pixel_resp_tx = pixel_resp_tx.clone();
thread::spawn(move || {
render_worker(i, &s, pixel_req_rx, &pixel_resp_tx);
});
}
// Retrieve the IDs of all active CPU cores.
let core_ids = core_affinity::get_core_ids().unwrap();
let core_ids = if core_ids.len() > num_threads {
core_ids[..num_threads].to_vec()
} else {
core_ids
};
info!("Creating {} render threads", core_ids.len());
// Create a thread for each active CPU core.
let mut handles = core_ids
.into_iter()
.enumerate()
.filter(|(i, _id)| *i < num_threads)
.map(|(i, id)| {
let s = sync::Arc::clone(&scene);
let pixel_req_rx = pixel_req_rx.clone();
let pixel_resp_tx = pixel_resp_tx.clone();
thread::spawn(move || {
core_affinity::set_for_current(id);
render_worker(i, &s, pixel_req_rx, &pixel_resp_tx);
})
})
.collect::<Vec<_>>();
drop(pixel_req_rx);
drop(pixel_resp_tx);
let start_time = time::Instant::now();
let (w, h) = (scene.width, scene.height);
thread::spawn(move || {
handles.push(thread::spawn(move || {
let batch_line_requests = true;
if batch_line_requests {
for y in 0..h {
@ -494,7 +509,7 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i
}
}
drop(pixel_req_tx);
});
}));
info!("Rendering with {} subsamples", scene.subsamples);
output::register_image(
@ -509,7 +524,7 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i
}
let pixel_total = scene.width * scene.height;
thread::spawn(move || {
handles.push(thread::spawn(move || {
let mut last_time = time::Instant::now();
let mut last_pixel_count = PIXEL_COUNT.load(Ordering::SeqCst);
let mut last_ray_count = RAY_COUNT.load(Ordering::SeqCst);
@ -524,7 +539,7 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i
let pixel_diff = pixel_count - last_pixel_count;
let ray_diff = ray_count - last_ray_count;
info!(
"{} / {} ({}%) pixels {} pixels/s {} rays/s",
"{} / {}pixels ({}%) {}pixels/s {}rays/s",
human.format(pixel_count as f64),
human.format(pixel_total as f64),
100 * pixel_count / pixel_total,
@ -534,8 +549,11 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i
last_time = now;
last_pixel_count = pixel_count;
last_ray_count = ray_count;
if pixel_count == pixel_total {
return;
}
}
});
}));
for resp in pixel_resp_rx {
match resp {
@ -549,11 +567,14 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i
}
}
}
for thr in handles {
thr.join().expect("thread join");
}
let human = human::Formatter::new();
let time_diff = time::Instant::now() - start_time;
let ray_count = RAY_COUNT.load(Ordering::SeqCst);
info!(
"{} pixels {} {}s pixels/s {} rays/s",
"{}pixels {:.2}s {}pixels/s {}rays/s",
human.format(pixel_total as f64),
time_diff.as_secs_f64(),
human.format(pixel_total as f64 / time_diff.as_secs_f64()),