Title image Project #5

Project 5: Circadian Signaling with Pthreads (due Friday Mar 16th at 11:59pm)

On NSCC, create a proj05 directory.

In this project, you will be making a threaded version of the circadian simulation code. You will simulate each network in parallel, not worrying about parallelizing the code within a network's simulation.

  1. Copy all of your code from the sequential circadian simulation. Update the Makefile to include -lpthread in the LFLAGS. Note: If there is any part of the sequential code that you would like from Stephanie, just let her know and she will share.
  2. Update the code to use rand_r.

    rand() is not thread-safe, so we must use a function that is. rand_r() is the reentrant version of rand, and it takes as input a pointer to a seed. Update generateGaussian as below:

    double generateGaussian(double mu, double sigma, unsigned int *seed)
    	static const double epsilon = DBL_MIN;
    	static const double two_pi = 2.0*3.14159265358979323846;
    	double z1, u1, u2;
    	   u1 = rand_r(seed) * (1.0 / RAND_MAX);
    	   u2 = rand_r(seed) * (1.0 / RAND_MAX);
    	while ( u1 <= epsilon );
    	double z0;
    	z0 = sqrt(-2.0 * log(u1)) * cos(two_pi * u2);
    	z1 = sqrt(-2.0 * log(u1)) * sin(two_pi * u2);
    	return z0 * sigma + mu;
    and then update generateGaussianPeriods to take in a pointer to an unsigned int. It should simply pass that seed along to generateGaussian.
    float *generateGaussianPeriods( int Nx, float mean, float std_dev, unsigned int *seed ) 

    Test your simulations with one of your simulation programs, such as sim_slow.

  3. Parallelize the main for loop in sim_stats_1s.c so that you create numTrials threads, each of which calls that function that implements the body of the loop. That thread function should also put the appropriate value into finalStds (note that an easy way to do this is to make finalStds a global variable). The thread function will need to generate a unique seed. A common approach is to use the clock. You may use this line of code to generate the seed:
        unsigned int seed = (id+1)*time(NULL);

    And when you call generateGaussianPeriods, pass it &seed;.

    Be sure to

    #include <time.h>
    at the top of the file.
  4. Test sim_stats_1s.c. You can compare the output of the new, parallellized, version with the sequential version from Project 3.
  5. Parallelize the main loop in sim_stats_ns.c using a similar approach to the one takenin sim_stats_1s.c.
  6. Test sim_stats_ns. You can compare the output of the new, parallellized, version with the sequential version from Project 3.

    Stephanie ran her code with 20 trials and 20 values of VIP strength (0 through 1.9 with a step of 0.1). If she used a VIP strength of 2.0, then it caused all the oscillators to halt, so she ended her VIP strength range at 1.9. The results appear in a box plot here:


  7. Analyze performance. Time your results when numTrials is varied. Do you get the expected speed-up? Do the run-times reveal to you how many processors you have?
  8. Analyze the output (e.g. the effect of VIP strength on synchrony).


Writeup and Handin

To hand in your project, you will gather all of the necessary files into a proj05 directory in your "turnin" directory:

  1. Create a file named README.txt. Describe the code files (the purpose of each file) along with how to compile and run the code.
  2. Create a second file for your project report. This one should allow for images or tables, so should be in a format such as .docx or .pdf. Include the analysis outlined earlier. The more thorough the analysis, the higher your grade will be. Also remember that a picture is worth 2^10 words.
  3. You should hand in all code necessary to run your solutions. Place all necessary .h, .c, and Makefile files in the proj05 directory. Stephanie will probably want to compile and run the code. It should be possible to do so without looking for any more files.

Zip up the directory and put it in your Private folder on Courses/CS336.