add multiple benchmark support, mandelbrot is still wip
This commit is contained in:
parent
b5df88f878
commit
d927f95d6a
5 changed files with 226 additions and 39 deletions
6
includes/mandelbrot.h
Normal file
6
includes/mandelbrot.h
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/* Lance le benchmark avec mandelbrot (TP10)
|
||||||
|
*
|
||||||
|
* Renvoie le temps d'exécution */
|
||||||
|
double benchmark_mandelbrot(int, int);
|
|
@ -1,3 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
int benchmark(int argc, char **argv);
|
/* Lance le benchmark avec quicksort (fournis)
|
||||||
|
*
|
||||||
|
* Renvoie le temps d'exécution */
|
||||||
|
double benchmark_quicksort(int, int);
|
||||||
|
|
57
src/main.c
57
src/main.c
|
@ -1,7 +1,62 @@
|
||||||
|
#include "../includes/mandelbrot.h"
|
||||||
#include "../includes/quicksort.h"
|
#include "../includes/quicksort.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
return benchmark(argc, argv);
|
int serial = 0;
|
||||||
|
int nthreads = -1;
|
||||||
|
|
||||||
|
int quicksort = 0;
|
||||||
|
int mandelbrot = 0;
|
||||||
|
double delay;
|
||||||
|
|
||||||
|
int opt;
|
||||||
|
while((opt = getopt(argc, argv, "qmst:")) != -1) {
|
||||||
|
if(opt < 0) {
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(opt) {
|
||||||
|
case 'q':
|
||||||
|
quicksort = 1;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
mandelbrot = 1;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
serial = 1;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
nthreads = atoi(optarg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(nthreads < 0 && !serial) {
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(quicksort) {
|
||||||
|
delay = benchmark_quicksort(serial, nthreads);
|
||||||
|
} else if(mandelbrot) {
|
||||||
|
delay = benchmark_mandelbrot(serial, nthreads);
|
||||||
|
} else {
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(delay >= 0.0);
|
||||||
|
printf("Done in %lf seconds.\n", delay);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
usage:
|
||||||
|
printf("Usage: %s -q|m [-t threads] [-s]\n", argv[0]);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
157
src/mandelbrot.c
Normal file
157
src/mandelbrot.c
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
#include "../includes/mandelbrot.h"
|
||||||
|
#include "../includes/sched.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <complex.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#define ITERATIONS 1000
|
||||||
|
|
||||||
|
struct mandelbrot_args {
|
||||||
|
unsigned int *image;
|
||||||
|
double scale;
|
||||||
|
int dx, dy, width, height;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mandelbrot_args *
|
||||||
|
new_mandelbrot_args(unsigned int *image, double scale, int dx, int dy,
|
||||||
|
int width, int height)
|
||||||
|
{
|
||||||
|
struct mandelbrot_args *args;
|
||||||
|
|
||||||
|
if(!(args = malloc(sizeof(struct mandelbrot_args)))) {
|
||||||
|
perror("Mandelbrot parameters");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
args->image = image;
|
||||||
|
args->scale = scale;
|
||||||
|
args->dx = dx;
|
||||||
|
args->dy = dy;
|
||||||
|
args->width = width;
|
||||||
|
args->height = height;
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mandel(double complex c)
|
||||||
|
{
|
||||||
|
double complex z = 0.0;
|
||||||
|
int i = 0;
|
||||||
|
while(i < ITERATIONS && creal(z) * creal(z) + cimag(z) * cimag(z) <= 4.0) {
|
||||||
|
z = z * z + c;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double complex
|
||||||
|
toc(int x, int y, int dx, int dy, double scale)
|
||||||
|
{
|
||||||
|
return ((x - dx) + I * (y - dy)) / scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
torgb(int n)
|
||||||
|
{
|
||||||
|
unsigned char r, g, b;
|
||||||
|
|
||||||
|
if(n < 128) {
|
||||||
|
int v = 2 * n;
|
||||||
|
r = v;
|
||||||
|
g = 0;
|
||||||
|
b = 255 - v;
|
||||||
|
} else if(n < 256) {
|
||||||
|
int v = 2 * (n - 128);
|
||||||
|
r = 0;
|
||||||
|
g = v;
|
||||||
|
b = 255 - v;
|
||||||
|
} else if(n < 512) {
|
||||||
|
int v = n - 256;
|
||||||
|
r = 255 - v;
|
||||||
|
g = v;
|
||||||
|
b = 0;
|
||||||
|
} else if(n < 1024) {
|
||||||
|
int v = (n - 512) / 2;
|
||||||
|
g = 255;
|
||||||
|
r = b = v;
|
||||||
|
} else {
|
||||||
|
r = g = b = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r << 16 | g << 8 | b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
draw(void *closure, struct scheduler *s)
|
||||||
|
{
|
||||||
|
struct mandelbrot_args *args = (struct mandelbrot_args *)closure;
|
||||||
|
unsigned int *image = args->image;
|
||||||
|
double scale = args->scale;
|
||||||
|
int dx = args->dx;
|
||||||
|
int dy = args->dy;
|
||||||
|
int width = args->width;
|
||||||
|
int height = args->height;
|
||||||
|
|
||||||
|
free(closure);
|
||||||
|
|
||||||
|
for(int y = 0; y < height; y++) {
|
||||||
|
for(int x = 0; x < width; x++) {
|
||||||
|
/* TODO: Utiliser s */
|
||||||
|
unsigned rgb = torgb(mandel(toc(x, y, dx, dy, scale)));
|
||||||
|
image[y * width + x] = rgb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
draw_serial(unsigned int *image, double scale, int dx, int dy, int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
for(int y = 0; y < height; y++) {
|
||||||
|
for(int x = 0; x < width; x++) {
|
||||||
|
unsigned rgb = torgb(mandel(toc(x, y, dx, dy, scale)));
|
||||||
|
image[y * width + x] = rgb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
benchmark_mandelbrot(int serial, int nthreads)
|
||||||
|
{
|
||||||
|
unsigned int *image;
|
||||||
|
struct timespec begin, end;
|
||||||
|
double delay;
|
||||||
|
int rc;
|
||||||
|
int width = 1920;
|
||||||
|
int height = 1080;
|
||||||
|
double scale = width / 4.0;
|
||||||
|
int dx = width / 2;
|
||||||
|
int dy = height / 2;
|
||||||
|
|
||||||
|
if(!(image = malloc(width * height * sizeof(unsigned int)))) {
|
||||||
|
perror("Image allocation");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &begin);
|
||||||
|
|
||||||
|
if(serial) {
|
||||||
|
draw_serial(image, scale, dx, dy, width, height);
|
||||||
|
} else {
|
||||||
|
rc = sched_init(
|
||||||
|
nthreads, width * height, draw,
|
||||||
|
new_mandelbrot_args(image, scale, dx, dy, width, height));
|
||||||
|
assert(rc >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &end);
|
||||||
|
delay = end.tv_sec + end.tv_nsec / 1000000000.0 -
|
||||||
|
(begin.tv_sec + begin.tv_nsec / 1000000000.0);
|
||||||
|
|
||||||
|
free(image);
|
||||||
|
return delay;
|
||||||
|
}
|
|
@ -93,43 +93,14 @@ quicksort(void *closure, struct scheduler *s)
|
||||||
assert(rc >= 0);
|
assert(rc >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
double
|
||||||
benchmark(int argc, char **argv)
|
benchmark_quicksort(int serial, int nthreads)
|
||||||
{
|
{
|
||||||
int *a;
|
int *a;
|
||||||
struct timespec begin, end;
|
struct timespec begin, end;
|
||||||
double delay;
|
double delay;
|
||||||
int rc;
|
int rc;
|
||||||
int n = 10 * 1024 * 1024;
|
int n = 10 * 1024 * 1024;
|
||||||
int nthreads = -1;
|
|
||||||
int serial = 0;
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
int opt = getopt(argc, argv, "sn:t:");
|
|
||||||
if(opt < 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
switch(opt) {
|
|
||||||
case 's':
|
|
||||||
serial = 1;
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
n = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
nthreads = atoi(optarg);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto usage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(n <= 0) {
|
|
||||||
goto usage;
|
|
||||||
}
|
|
||||||
if(nthreads < 0 && !serial) {
|
|
||||||
goto usage;
|
|
||||||
}
|
|
||||||
|
|
||||||
a = malloc(n * sizeof(int));
|
a = malloc(n * sizeof(int));
|
||||||
|
|
||||||
|
@ -152,16 +123,11 @@ benchmark(int argc, char **argv)
|
||||||
clock_gettime(CLOCK_MONOTONIC, &end);
|
clock_gettime(CLOCK_MONOTONIC, &end);
|
||||||
delay = end.tv_sec + end.tv_nsec / 1000000000.0 -
|
delay = end.tv_sec + end.tv_nsec / 1000000000.0 -
|
||||||
(begin.tv_sec + begin.tv_nsec / 1000000000.0);
|
(begin.tv_sec + begin.tv_nsec / 1000000000.0);
|
||||||
printf("Done in %lf seconds.\n", delay);
|
|
||||||
|
|
||||||
for(int i = 0; i < n - 1; i++) {
|
for(int i = 0; i < n - 1; i++) {
|
||||||
assert(a[i] <= a[i + 1]);
|
assert(a[i] <= a[i + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(a);
|
free(a);
|
||||||
return 0;
|
return delay;
|
||||||
|
|
||||||
usage:
|
|
||||||
printf("quicksort [-n size] [-t threads] [-s]\n");
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue