void Phx::Step(float delta) { if(gravitation) // Dodajemy grawitacje ApplyGravitation(); for(int i=0;i<DynamicList.size();i++) // Liczymy si³y DynamicList[i]->CalcForces(delta); SearchForCollisions(); // Szukamy kolizji for(int i=0;i<Collisions.size();i++) // Liczymy wstêpne dane Collisions[i]->Initialize(delta,Gravity); for(int i=0;i<10;i++) { for(int i=0;i<Collisions.size();i++) Resolve(Collisions[i],delta); // Rozwi¹zujemy wszystkie wykryte kolizje ResolveJoints(delta); // Rozwi¹zujemy po³¹czenia } PositionalCorrection(); // Korygujemy pozycje MoveBodies(delta); // Poruszamy obiekty for(int i=0;i<DynamicList.size();i++) DynamicList[i]->CalcForces(delta); for(int i=0;i<DynamicList.size();i++) { DynamicList[i]->force.clear(); DynamicList[i]->torque = 0; } }
int main(const int argc, const char** argv) { // Problem size and other parameters const int nBodies = (argc > 1 ? atoi(argv[1]) : 16384); const int nSteps = 10; // Duration of test const float dt = 0.01f; // Body propagation time step // Body data stored as an Array of Structures (AoS) struct BodyType bodies[nBodies]; // Initialize random number generator and bodies srand(0); float randmax; randmax = (float) RAND_MAX; for(int i = 0; i < nBodies; i++) { bodies[i].x = ((float) rand())/randmax; bodies[i].y = ((float) rand())/randmax; bodies[i].z = ((float) rand())/randmax; bodies[i].vx = ((float) rand())/randmax; bodies[i].vy = ((float) rand())/randmax; bodies[i].vz = ((float) rand())/randmax; } // Compute initial center of mass float comx = 0.0f, comy=0.0f, comz=0.0f; for (int i=0; i<nBodies; i++) { comx += bodies[i].x; comy += bodies[i].y; comz += bodies[i].z; } comx = comx / nBodies; comy = comy / nBodies; comz = comz / nBodies; printf("Initial center of mass: (%g, %g, %g)\n", comx, comy, comz); // Perform benchmark printf("\n\033[1mNBODY Version 01\033[0m\n"); printf("\nPropagating %d bodies using 1 thread on %s...\n\n", nBodies, "CPU"); double rate = 0, dRate = 0; // Benchmarking data const int skipSteps = 3; // Set this to a positive int to skip warm-up steps printf("\033[1m%5s %10s %10s %8s\033[0m\n", "Step", "Time, s", "Interact/s", "GFLOP/s"); fflush(stdout); for (int step = 1; step <= nSteps; step++) { const double tStart = omp_get_wtime(); // Start timing MoveBodies(nBodies, bodies, dt); const double tEnd = omp_get_wtime(); // End timing // These are for calculating flop rate. It ignores symmetry and // estimates 20 flops per body-body interaction in MoveBodies const float HztoInts = (float)nBodies * (float)(nBodies-1) ; const float HztoGFLOPs = 20.0*1e-9*(float)nBodies*(float)(nBodies-1); if (step > skipSteps) { // Collect statistics rate += HztoGFLOPs / (tEnd - tStart); dRate += HztoGFLOPs * HztoGFLOPs / ((tEnd-tStart)*(tEnd-tStart)); } printf("%5d %10.3e %10.3e %8.1f %s\n", step, (tEnd-tStart), HztoInts/(tEnd-tStart), HztoGFLOPs/(tEnd-tStart), (step<=skipSteps?"*":"")); fflush(stdout); } rate/=(double)(nSteps-skipSteps); dRate=sqrt(fabs(dRate/(double)(nSteps-skipSteps)-rate*rate)); printf("-----------------------------------------------------\n"); printf("\033[1m%s %4s \033[42m%10.1f +- %.1f GFLOP/s\033[0m\n", "Average performance:", "", rate, dRate); printf("-----------------------------------------------------\n"); printf("* - warm-up, not included in average\n\n"); // Compute final center of mass comx = 0.0f; comy=0.0f; comz=0.0f; for (int i=0; i<nBodies; i++) { comx += bodies[i].x; comy += bodies[i].y; comz += bodies[i].z; } comx = comx / nBodies; comy = comy / nBodies; comz = comz / nBodies; printf("Final center of mass: (%g, %g, %g)\n", comx, comy, comz); }