diff --git a/bench b/bench new file mode 100755 index 0000000..71ecc54 Binary files /dev/null and b/bench differ diff --git a/bench.c b/bench.c new file mode 100644 index 0000000..392a85e --- /dev/null +++ b/bench.c @@ -0,0 +1,179 @@ +#include +#include +#include +#include +#include +#include +#include "images/images.h" +#include "marcher.h" + +typedef int bool; +#define true 1 +#define false 0 + +#define BENCH_VERSION "1.0" + + +/* + + Mandelbulb scene object + + Currently cannot be set at a specific location, always resides at origin (0,0,0) + + Color function is just a flat shader, detail is displayed with ambient occlusion + +*/ +double mandelbulb_dist(Point pt, SceneObject *self) { + int iters = self->args[0]; + double power = self->args[1]; + + Point z = pt; + float dr = 1.0; + float r = 0.0; + for (int i = 0; i < iters ; i++) { + r = pt_length(z); + + if (r>2) { + break; + } + + // convert to polar coordinates + float theta = acos(z.z/r); + float phi = atan2(z.y,z.x); + dr = pow(r, power-1.0)*power*dr + 1.0; + + // scale and rotate the point + float zr = pow(r, power); + theta = theta*power; + phi = phi*power; + + // convert back to cartesian coordinates + z = pt_mult(pt_new(sin(theta)*cos(phi), sin(phi)*sin(theta), cos(theta)), zr); + pt_add(&z, pt); + } + + return 0.5*log(r)*r/dr; + +} + +Color mandelbulb_color(Point hit, Point direction, SceneObject *self) { + return self->color; +} + +// constructs the scene object +SceneObject mandelbulb_new(Point location, int iters, double power) { + SceneObject so; + so.location = location; + so.args = malloc(sizeof(double) * 3); + so.args[0] = iters; // iterations + so.args[1] = power; // power + so.args[2] = -1; // reserved for color calculations + so.distance = mandelbulb_dist; + so.get_color = mandelbulb_color; + so.color = color_new(255,255,255); + return so; +} + +int run_bench(int size, float pow, int threads, const char path[], bool save) { + float cam_position = 1.15; + int steps = 2000; + int iters = 1000; + float threshold = 0.0001; + + Camera cam; + cam.fov = 90; + + camera_set_looking_at(&cam, pt_new(cam_position, cam_position, cam_position), pt_new(0,0,0)); + + // create basic scene with up to 10 objects + Scene scene = scene_new(size, size, 1); + scene.perf_opts.max_steps = steps; + scene.perf_opts.threshold = threshold; + scene.perf_opts.speed_cutoff = 10; + scene.background = color_new(0,0,0); + + scene_add_obj(&scene, mandelbulb_new(pt_new(0,0,0), iters, pow)); + + Image *img = render_scene(&scene, &cam, threads); + + if (save) { + image_save_bmp(*img, path); + } + + image_destroy_shared(*img); + scene_destroy(scene); + + return 0; +} + +struct timer { + struct timeval start; + struct timeval end; + char *name; +}; + +void timer_start(struct timer *t) { + printf("\n\n\nStarting bench %s\n", t->name); + gettimeofday(&t->start, NULL); +} +void timer_end(struct timer *t) { + gettimeofday(&t->end, NULL); +} +void timer_print(struct timer t) { + long time, secs, usecs; + secs = t.end.tv_sec - t.start.tv_sec; + usecs = t.end.tv_usec - t.start.tv_usec; + time = ((secs) * 1000 + usecs/1000.0) + 0.5; + printf("\nBenchmark %s took %ldms (%.2fs)\n", t.name, time, time / 1000.0f); +} + +int main(int argc, char *argv[]) +{ + int threads = get_nprocs(); + struct timer bench; + int size = 1080; + + printf("Mandelbulb Benchmark v%s\n\nDetected %d threads...\n", BENCH_VERSION, threads); + + sleep(2); + + bench.name = "1080px render with saving"; + timer_start(&bench); + run_bench(1080, 3.0, threads, "bench-pow3-1080p.bmp", true); + timer_end(&bench); + timer_print(bench); + + sleep(2); + + bench.name = "1080px render without saving"; + timer_start(&bench); + run_bench(1080, 3.0, threads, "", false); + timer_end(&bench); + timer_print(bench); + + sleep(2); + + bench.name = "10 megapixel render with saving"; + timer_start(&bench); + run_bench(3162, 3.0, threads, "bench-pow3-10mpx.bmp", true); + timer_end(&bench); + timer_print(bench); + + sleep(2); + + bench.name = "40 megapixel render with saving"; + timer_start(&bench); + run_bench(6324, 3.0, threads, "bench-pow3-40mpx.bmp", true); + timer_end(&bench); + timer_print(bench); + + sleep(2); + + bench.name = "1080px render single threaded without saving"; + timer_start(&bench); + run_bench(1080, 3.0, 1, "", false); + timer_end(&bench); + timer_print(bench); + + return 0; +} diff --git a/src/camera.c b/src/camera.c index fd205e4..6cbfd53 100644 --- a/src/camera.c +++ b/src/camera.c @@ -105,11 +105,7 @@ void camera_iterate_rays_const_dist(Camera camera, int width, int height, int th // get rotation axis pt_orthogonal_plane(camera.direction, &span_z, &span_xy); - printf("rendering %ix%i px\n", width, height); - - pt_print_n("span_xy", span_xy); - pt_print_n("span_z", span_z); - + printf("rendering %ix%ipx\n", width, height); // distance each ray has from anothe on the ortogonal plane double step_dist = 2 / (double) (width - 1); @@ -118,7 +114,6 @@ void camera_iterate_rays_const_dist(Camera camera, int width, int height, int th Point move_right = pt_scale(span_xy, step_dist); Point move_up = pt_scale(span_z, step_dist);; - printf("step: %f\n", step_dist); // set starting point Point starting_point = pt_normalize(camera.direction); @@ -161,7 +156,6 @@ void camera_iterate_rays_const_dist(Camera camera, int width, int height, int th } if (thread_id != 0) { - printf("Thread %i is finished\n", thread_id); exit(0); } @@ -169,6 +163,4 @@ void camera_iterate_rays_const_dist(Camera camera, int width, int height, int th for (int i = 0; i < threads - 1; i++) { while(wait(&status) > 0) {} } - - printf("got threads\n"); } \ No newline at end of file