aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian T <julian@jtle.dk>2021-02-12 23:33:50 +0100
committerJulian T <julian@jtle.dk>2021-02-12 23:34:09 +0100
commit14f7b47f2c2315d0de5e52d31c57fe07a15d08ad (patch)
treef512e7e0939fd151cf9196004611e3cd82a95773
parent49c6adb0db70ffc30eaac33b66eacf7574b34e26 (diff)
Implement multithreaded compiling of tiles
-rw-r--r--Cargo.lock25
-rw-r--r--Cargo.toml1
-rw-r--r--src/main.rs12
-rw-r--r--src/render/coordinator.rs14
-rw-r--r--src/sample/mod.rs2
-rw-r--r--src/sample/uniform.rs6
-rw-r--r--src/world/mod.rs8
7 files changed, 57 insertions, 11 deletions
diff --git a/Cargo.lock b/Cargo.lock
index c9f49c0..370504f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -64,6 +64,20 @@ dependencies = [
]
[[package]]
+name = "crossbeam"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd01a6eb3daaafa260f6fc94c3a6c36390abc2080e38e3e34ced87393fb77d80"
+dependencies = [
+ "cfg-if",
+ "crossbeam-channel",
+ "crossbeam-deque",
+ "crossbeam-epoch",
+ "crossbeam-queue",
+ "crossbeam-utils",
+]
+
+[[package]]
name = "crossbeam-channel"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -99,6 +113,16 @@ dependencies = [
]
[[package]]
+name = "crossbeam-queue"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f6cb3c7f5b8e51bc3ebb73a2327ad4abdbd119dc13223f14f961d2f38486756"
+dependencies = [
+ "cfg-if",
+ "crossbeam-utils",
+]
+
+[[package]]
name = "crossbeam-utils"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -370,6 +394,7 @@ dependencies = [
name = "rendering"
version = "0.1.0"
dependencies = [
+ "crossbeam",
"image",
"rand",
"rand_pcg",
diff --git a/Cargo.toml b/Cargo.toml
index 09f2c2e..629e22f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,3 +10,4 @@ edition = "2018"
image = "0.23.12"
rand = "0.8.3"
rand_pcg = "0.3.0"
+crossbeam = "0.8.0"
diff --git a/src/main.rs b/src/main.rs
index 215e0d4..0f6502e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,7 +6,7 @@ use rendering::render::{RenderContext, RenderCoord};
use rendering::sample::UniformSampler;
use rendering::material::{Reflectant, Lambertian};
-use std::rc::Rc;
+use std::sync::Arc;
fn main() {
let res = Vector2i::new_xy(500, 500);
@@ -21,9 +21,9 @@ fn main() {
aperture: Some(20.0),
});
- let brown = Rc::new(Lambertian::new(Spectrum::new_rgb(0.5, 0.3, 0.0)));
- let blue = Rc::new(Lambertian::new(Spectrum::new_rgb(0.0, 0.3, 0.7)));
- let metal = Rc::new(Reflectant::new(Spectrum::new_rgb(0.75, 0.75, 0.75), None));
+ let brown = Arc::new(Lambertian::new(Spectrum::new_rgb(0.5, 0.3, 0.0)));
+ let blue = Arc::new(Lambertian::new(Spectrum::new_rgb(0.0, 0.3, 0.7)));
+ let metal = Arc::new(Reflectant::new(Spectrum::new_rgb(0.75, 0.75, 0.75), None));
let mut scn = Scene::new();
scn.add_objects(vec![
@@ -40,9 +40,9 @@ fn main() {
let mut film = Film::new(res);
{
- let coord = RenderCoord::new(&mut film, Vector2i::new_xy(32, 32), 100);
+ let coord = RenderCoord::new(&mut film, Vector2i::new_xy(32, 32), 300);
- coord.work(&ctx, &mut sampler);
+ coord.run_threaded(&ctx, &mut sampler, 8);
}
let image = film.finalize_image();
diff --git a/src/render/coordinator.rs b/src/render/coordinator.rs
index a9a7d06..a8d8afb 100644
--- a/src/render/coordinator.rs
+++ b/src/render/coordinator.rs
@@ -7,7 +7,8 @@ use crate::camera::Film;
use crate::core::{Bound2i, Vector2i};
use crate::sample::Sampler;
-use std::sync::Mutex;
+use std::sync::{Arc, Mutex};
+use std::thread;
struct Tiler {
tilesize: Vector2i,
@@ -112,4 +113,15 @@ impl<'a> RenderCoord<'a> {
self.finish_task(&task);
}
}
+
+ pub fn run_threaded(&self, ctx: &RenderContext, sampler: &mut (dyn Sampler + Send), threads: u32) {
+ crossbeam::scope(|scope| {
+ for _ in 0..threads {
+ let mut sampler = sampler.clone_and_seed();
+ scope.spawn(move |_| {
+ self.work(ctx, sampler.as_mut());
+ });
+ }
+ }).unwrap();
+ }
}
diff --git a/src/sample/mod.rs b/src/sample/mod.rs
index 88e1aa9..1a53921 100644
--- a/src/sample/mod.rs
+++ b/src/sample/mod.rs
@@ -16,6 +16,8 @@ pub trait Sampler {
Vector2f::new_xy(self.get_sample(), self.get_sample())
}
+ fn clone_and_seed(&mut self) -> Box<dyn Sampler + Send>;
+
fn get_unit_vector(&mut self) -> Vector3f {
let s2d = self.get_sample_2d();
diff --git a/src/sample/uniform.rs b/src/sample/uniform.rs
index 2cd3156..c144f27 100644
--- a/src/sample/uniform.rs
+++ b/src/sample/uniform.rs
@@ -30,4 +30,10 @@ impl Sampler for UniformSampler {
fn get_sample(&mut self) -> Float {
self.d.sample(&mut self.r)
}
+
+ fn clone_and_seed(&mut self) -> Box<dyn Sampler + Send> {
+ let mut n = self.clone();
+ n.r = Pcg32::seed_from_u64(self.r.next_u64());
+ Box::new(n)
+ }
}
diff --git a/src/world/mod.rs b/src/world/mod.rs
index ef239db..f0ba8d2 100644
--- a/src/world/mod.rs
+++ b/src/world/mod.rs
@@ -4,17 +4,17 @@ pub mod shapes;
mod scene;
pub use scene::*;
-use std::rc::Rc;
+use std::sync::Arc;
use crate::core::Hittable;
use crate::material::Material;
pub struct Object {
- pub shape: Box<dyn Hittable>,
- pub mat: Rc<dyn Material>,
+ pub shape: Box<dyn Hittable + Sync>,
+ pub mat: Arc<dyn Material + Sync + Send>,
}
impl Object {
- pub fn new(mat: Rc<dyn Material>, shape: Box<dyn Hittable>) -> Self {
+ pub fn new(mat: Arc<dyn Material + Sync + Send>, shape: Box<dyn Hittable + Sync>) -> Self {
Object {
mat,
shape,