![]() |
![]() |
![]() |
Here is the source code for a simple program that generates images of the Mandelbrot set and displays them in a graphics window. Just download all of the files, run make to build the code, and then ./fractal to display.
This program uses the escape time algorithm. For each pixel in the image, it starts with the x and y position, and then computes a recurrence relation until it exceeds a fixed value or runs for max iterations.
static int compute_point( double x, double y, int maxiter ) { double complex z = 0; double complex alpha = x + I*y; int iter = 0; while( cabs(z)<4 && iter < maxiter ) { z = cpow(z,2) + alpha; iter++; } return iter; }
Then, the pixel is assigned a color according to the number of iterations completed. An easy color scheme is to assign a gray value proportional to the number of iterations, but others are possible. Here are a few color variations of the same configuration:
![]() |
![]() |
![]() |
The maxiter value controls the amount of work done by the algorithm. If we increase maxiter, then we can see much more detail in the set, but it may take much longer to compute. Generally speaking, you need to turn the maxiter value higher as you zoom in. For example, here is the same area in the set computed with four different values of maxiter:
xmin .286682 xmax .287182 ymin .014037 ymax .014537 | |||
maxiter 50 | maxiter 100 | maxiter 500 | maxiter 1000 |
![]() |
![]() |
![]() |
![]() |
Play around with the tool for a bit, and find an interesting area that takes more than ten seconds to compute. You can increase the computation time by either increasing the size of the window, or by increasing the maxiter value to compute more detail.
Once the interactive program works as desired, keep that version in the file fractal.c
Modify fractalthread.c to use multiple threads to compute the image. Each thread should compute a completely separate band of the image. For example, if you specify three threads and the image is 600 pixels high, then thread 0 should work on lines 0-199, thread 1 should work on lines 200-399, and thread 2 should work on lines 400-599.
The number of threads should be adjustable at runtime via the keyboard. If the user presses any of the keys 1-8, the next image should be computed using that number of threads.
Now, the trick here is that each thread is going to be using the graphics library to set the color and draw a pixel on the screen. Without any protection, the program will simply crash as the threads compete with each other. (In fact, you should try it, and see where it crashes) Identify the critical section in the program and protect it with a pthread mutex.
Explore the Mandelbrot set some more using fractalthread. It should be noticeably faster when using multiple threads, since the student machines (particularly student10-13) have a large number of cores. However, notice that in some cases, the threads do not all finish at the same time. If one section of the image takes longer to compute, some threads will be idle while the others are still working. Let's fix that problem in the next step.
To solve the load imbalance, we must divide the work up into even smaller units called tasks. Suppose that we define each individual horizontal line of the image as a separate task to be completed. Declare an array tasks[i] to keep track of which tasks have and have not been started. Then, set up each thread such that it runs in a loop, selects the next available task, computes it, and then repeats until all tasks are complete. Again, you must be careful because tasks is a data structure shared among multiple threads. Identify the critical section and protect it with a pthread mutex.
gfx_wait() will wait until a mouse button or key is pressed, and then return an integer representing that mouse button or key. In the case of a printable letter, it's just the ASCII value of that letter (treat it like a char). Mouse buttons and special keys are represented by unique numbers which you can discover by just printing out the return value of gfx_wait()
This assignment is due at 5:30PM on Friday, February 21st. Late assignments are not accepted. Please review the general instructions for assignments.