For this lab, you will parallelize a single-threaded implementation of an n-body simulation. An n-body simulation models the movement of n massive objects acting on each other gravitationally. Every pair of stars has some gravitational effect, and to compute the total effect on each star we have to consider all pairs of stars. This results in a lot of repeated computation, which is a good target for parallelization.
During the course of this lab, you’ll learn some very basic C++.
Specifically, this project uses C++’s operator overloading to provide a convenient class that represents two-dimensional vectors.
The project does use other C++ standard features like std::vector (which is similar to Java’s ArrayList) and some additional classes to make the code a bit cleaner.
If you run into some C++ code you don’t understand or you are interested in using C++ features for your component of this lab, cppreference.com is a good resource for the C++ standard library.
In particular, the C++ thread API eliminates much of the boilerplate code you have to write to create threads in C.
I am happy to give explanations or quick tutorials on C++, but I expect most of the code you write will be very C-like for this lab.
The starter code is available on GitHub at grinnell-cs/213-galaxy. Follow the usual procedure for forking this repository and adding your partner as a collaborator.

This section describes the basic organization of the provided code.
For this project, we are using the .cc and .hh file extensions for C++ source and header files, respectively.
The suffixes .cpp and .hpp are also common, but sometimes you’ll see C++ include files that just end in .h.
We’ll walk through each file here:
updateStars function.
This code merges stars that are close enough to collide, then computes the force on each star and updates its position.
This is where you will make most of your changes, although you are welcome to add additional source files if you like.bitmap class. This class represents an image as an array of RGB colors. Your raytracing code generates colors as vectors of three floating point numbers, and this class converts them to RGB colors with components between 0 and 255. This class also includes code for copying a bitmap into the display. You do not need to change this file.gui class, which hides some of the setup and management of an SDL window. You can pass a bitmap to the display(bitmap bmp) function to display that bitmap on the screen. Note that there is an alternate version that takes coordinates and a size to display a bitmap on just part of the screen. You do not need to change this file.star class.
This class tracks the mass, position, velocity, and color of an individual star.
You can also use this class to accumulate force vectors on a given star, then update its position and velocity according to that force.time_ms() and wait_ms(size_t) functions we’ve used before. These functions are marked as static, which means something different than “static” in Java, at least in this context. Marking a function as static in this context means it is private to the current source file, so it can be defined in multiple sources. Without this keyword, the compiler would give a “multiple definitions” error. You do not need to change this file.vec2d class, which represents a two-dimensional vector. This class makes extensive use of “operator overloading,” which allows you to define operators like +, -, *, and so on for your own classes. You do not need to change this file.Build the program with make, then run ./galaxy to start the simulation.
Clicking on the screen will create a random “galaxy” of stars moving in a somewhat-random circular pattern.
If stars drift out of view, you can use the arrow keys to move the viewport.
Your task is to implement a parallel work queue for this n-body simulation. The work queue will serve as a point of communication between the main user interface and worker threads that will perform the n-body simulation calculations. Your final implementation should follow this general structure.
updateStars to merge collided stars.
You do not need to run this task in parallel.stars data structure.
The loop on line 173 of main.cc contains the work you should run in parallel.
A worker thread should “grab” a star, compute all the forces on that star, and then update its position.
There will be a race condition on individual stars;
a star may be update as another thread reads its location.
This is acceptable, since stars will not move large distances in a single update.
You can leave this race condition in place to avoid the cost of locking.man page for pthread_barrier_wait) to implement this feature.
Make sure that every worker thread has finished processing its last star before you allow the main thread to proceed.In addition to parallelizing this n-body simulation, you will also conduct a small performance evaluation of your implementation. Add code to track the number of stars being simulated and the time to run a single frame of the simulation, which you can output to the terminal in CSV format, which you can open in most spreadsheet programs.
Collect information that shows how the time to compute a single frame varies with the number of stars and the number of worker threads. You should try 1, 2, 4, and 8 worker threads, as well as the original serial version of the program. By plotting each of these as a separate series, you can see how adding worker threads changes performance. Comparing the serial version with your parallel version using a single worker thread shows you the added cost of your parallel implementation.
Add your graph to the repository and include a brief description of your findings in a README.md file in your repository.