Skip to content

Commit c48e8c8

Browse files
chore: add raytracer multithreading
1 parent b6a3368 commit c48e8c8

File tree

2 files changed

+71
-12
lines changed

2 files changed

+71
-12
lines changed

src/InOneWeekend/camera.h

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@
1313

1414
#include "hittable.h"
1515
#include "material.h"
16-
16+
#include <sys/mman.h>
17+
#include <unistd.h>
18+
#include <stdio.h>
19+
#include <sys/types.h>
20+
#include <sys/wait.h>
1721

1822
class camera {
1923
public:
@@ -30,26 +34,62 @@ class camera {
3034
double defocus_angle = 0; // Variation angle of rays through each pixel
3135
double focus_dist = 10; // Distance from camera lookfrom point to plane of perfect focus
3236

33-
void render(const hittable& world) {
37+
void render(const hittable& world, int processes) {
3438
initialize();
3539

3640
std::cout << "P3\n" << image_width << ' ' << image_height << "\n255\n";
3741

38-
for (int j = 0; j < image_height; j++) {
39-
std::clog << "\rScanlines remaining: " << (image_height - j) << ' ' << std::flush;
40-
for (int i = 0; i < image_width; i++) {
41-
color pixel_color(0,0,0);
42-
for (int sample = 0; sample < samples_per_pixel; sample++) {
43-
ray r = get_ray(i, j);
44-
pixel_color += ray_color(r, max_depth, world);
42+
int image_size_in_bytes = sizeof(color) * image_width * image_height;
43+
color *rendered_image = (color *) mmap(nullptr, image_size_in_bytes,
44+
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
45+
46+
int lines_per_child = image_height / processes;
47+
int remainder = image_height % processes;
48+
49+
std::clog << "Rendering " << image_height << " lines with " << processes << " processes.\n";
50+
std::clog << lines_per_child << " lines per child, " << remainder << " remainder.\n";
51+
52+
pid_t pid;
53+
for (int i = 0; i < processes; i++) {
54+
pid = fork();
55+
if (pid == 0) {
56+
for (int j = i * lines_per_child; j < (i + 1) * lines_per_child; j++) {
57+
renderLine(j, world, rendered_image);
4558
}
46-
write_color(std::cout, pixel_samples_scale * pixel_color);
59+
std::clog << "Child process " << i << " done. \n";
60+
exit(0);
61+
}
62+
}
63+
64+
for (int i = 0; i < remainder; i++) {
65+
renderLine(i, world, rendered_image);
66+
}
67+
std::clog << "Remainder done. \n";
68+
69+
for (int i = 0; i < processes; i++) {
70+
wait(NULL);
71+
}
72+
73+
for (int i = 0; i < image_height; i++) {
74+
for (int j = 0; j < image_width; j++) {
75+
write_color(std::cout, rendered_image[i * image_width + j]);
4776
}
4877
}
4978

5079
std::clog << "\rDone. \n";
5180
}
5281

82+
void renderLine(int line, const hittable &world, color *rendered_image) {
83+
for (int i = 0; i < image_width; i++) {
84+
color pixel_color(0,0,0);
85+
for (int sample = 0; sample < samples_per_pixel; sample++) {
86+
ray r = get_ray(i, line);
87+
pixel_color += ray_color(r, max_depth, world);
88+
}
89+
rendered_image[line * image_width + i] = pixel_samples_scale * pixel_color;
90+
}
91+
}
92+
5393
private:
5494
int image_height; // Rendered image height
5595
double pixel_samples_scale; // Color scale factor for a sum of pixel samples

src/InOneWeekend/main.cc

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
#include "hittable_list.h"
1717
#include "material.h"
1818
#include "sphere.h"
19+
#include <stdio.h>
20+
#include <sys/time.h>
1921

2022

21-
int main() {
23+
int main(int argc, char *argv[]) {
2224
hittable_list world;
2325

2426
auto ground_material = make_shared<lambertian>(color(0.5, 0.5, 0.5));
@@ -76,5 +78,22 @@ int main() {
7678
cam.defocus_angle = 0.6;
7779
cam.focus_dist = 10.0;
7880

79-
cam.render(world);
81+
int n = 1;
82+
if(argc > 1) {
83+
n = atoi(argv[1]);
84+
}
85+
86+
struct timeval start, end;
87+
long seconds, useconds;
88+
double duration;
89+
90+
gettimeofday(&start, NULL);
91+
cam.render(world, n);
92+
gettimeofday(&end, NULL);
93+
94+
seconds = end.tv_sec - start.tv_sec;
95+
useconds = end.tv_usec - start.tv_usec;
96+
duration = seconds + useconds/1000000.0;
97+
98+
std::clog << "Time taken: " << duration << " seconds" << std::endl;
8099
}

0 commit comments

Comments
 (0)