3 * @purpose OpenMP version of N-Body simulator, implementation
4 * @author Sam Moore (20503628) - 2012
8 #include "../single-thread/nbody.c" // Include original code
9 #include "graphics.h" // For Graphics_Run function only
12 * @function Simulation_Run
13 * @purpose Start the simulation
14 * @param argc, argv - Passed to Graphics_Run if needed, otherwise unused
16 void Simulation_Run(int argc, char ** argv)
19 if (omp_get_nested() != 1)
21 fprintf(stderr, "Couldn't set nested parallelism, I kind of need that\n");
26 if (options.num_threads == 0)
27 options.num_threads = omp_get_max_threads();
29 if (options.draw_graphics)
30 omp_set_num_threads(2);
32 omp_set_num_threads(1);
37 #pragma omp parallel sections
42 omp_set_num_threads(options.num_threads);
46 if (runstate != RUN) break; //Check whether the main thread wants to exit
54 if (options.draw_graphics == false && options.verbosity != 0
55 && universe.steps % options.verbosity == 1)
63 //printf("Left compute loop\n");
68 if (options.draw_graphics)
69 Graphics_Run(argc, argv);
70 //printf("Got to bit after Graphics_Run()\n");
78 * @purpose Compute a single step, multithreaded using OpenMP
82 //printf("There are %d threads working and %d available\n", omp_get_num_threads(), omp_get_max_threads());
84 unsigned n_per_thread = (universe.N) / options.num_threads;
85 unsigned remainder = (universe.N) % options.num_threads;
86 #pragma omp parallel for
87 for (unsigned i = 0; i < options.num_threads; ++i)
89 //printf("Thread %d executes iteration %u\n", omp_get_thread_num(), i);
91 s.body = universe.body + (i * n_per_thread);
92 s.N = (i == options.num_threads - 1) ? n_per_thread : n_per_thread + remainder;
93 System_Forces(&s, &universe);
96 #pragma omp parallel for
97 for (unsigned i = 0; i < options.num_threads; ++i)
99 //printf("Thread %d executes iteration %u\n", omp_get_thread_num(), i);
101 s.body = universe.body + (i * n_per_thread);
102 s.N = (i == options.num_threads - 1) ? n_per_thread : n_per_thread + remainder;
103 System_Positions(&s);