//--------------------------------------------------------------------- // Orbital Simulator // This program currently runs an N-body simulation using a basic // brute force algorithm and renders the bodies onto the screen. Future // additions include an implementation of the Barnes-Hut algorithm, // generation of large-N systems, and path trajectory/maneuver // calculations. See the README for more info. //--------------------------------------------------------------------- int main() { sf::RenderWindow window(sf::VideoMode(orbutil::SCREEN_WIDTH, orbutil::SCREEN_HEIGHT), "Orbit Simulator"); sf::Clock clock; sf::Time timeSinceLastUpdate; BodySystem system; while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) window.close(); else if (event.type == sf::Event::KeyPressed) { if (event.key.code == sf::Keyboard::Escape) window.close(); } } timeSinceLastUpdate = clock.restart(); system.update(timeSinceLastUpdate); window.clear(); window.draw(system); window.display(); } return 0; }
void _runBenchmark(int iterations) { // once without timing to prime the device if (!useCpu) { m_nbody->update(activeParams.m_timestep); } if (useCpu) { sdkCreateTimer(&timer); sdkStartTimer(&timer); } else { checkCudaErrors(cudaEventRecord(startEvent, 0)); } for (int i = 0; i < iterations; ++i) { m_nbody->update(activeParams.m_timestep); } float milliseconds = 0; if (useCpu) { sdkStopTimer(&timer); milliseconds = sdkGetTimerValue(&timer); sdkStartTimer(&timer); } else { checkCudaErrors(cudaEventRecord(stopEvent, 0)); checkCudaErrors(cudaEventSynchronize(stopEvent)); checkCudaErrors(cudaEventElapsedTime(&milliseconds, startEvent, stopEvent)); } double interactionsPerSecond = 0; double gflops = 0; computePerfStats(interactionsPerSecond, gflops, milliseconds, iterations); printf("%d bodies, total time for %d iterations: %.3f ms, mean %f\n", numBodies, iterations, milliseconds, milliseconds/iterations); printf("= %.3f billion interactions per second\n", interactionsPerSecond); printf("= %.3f %s-precision GFLOP/s at %d flops per interaction\n", gflops, (sizeof(T) > 4) ? "double" : "single", flopsPerInteraction); }
bool _compareResults(int numBodies) { assert(m_nbodyCuda); bool passed = true; m_nbody->update(0.001f); { m_nbodyCpu = new BodySystemCPU<T>(numBodies); m_nbodyCpu->setArray(BODYSYSTEM_POSITION, m_hPos); m_nbodyCpu->setArray(BODYSYSTEM_VELOCITY, m_hVel); m_nbodyCpu->update(0.001f); T *cudaPos = m_nbodyCuda->getArray(BODYSYSTEM_POSITION); T *cpuPos = m_nbodyCpu->getArray(BODYSYSTEM_POSITION); T tolerance = 0.0005f; for (int i = 0; i < numBodies; i++) { if (fabs(cpuPos[i] - cudaPos[i]) > tolerance) { passed = false; printf("Error: (host)%f != (device)%f\n", cpuPos[i], cudaPos[i]); } } } return passed; }
void _reset(int numBodies, NBodyConfig config) { if (tipsyFile == "") { randomizeBodies(config, m_hPos, m_hVel, m_hColor, activeParams.m_clusterScale, activeParams.m_velocityScale, numBodies, true); setArrays(m_hPos, m_hVel); } else { m_nbody->loadTipsyFile(tipsyFile); ::numBodies = m_nbody->getNumBodies(); } }
void _init(int numBodies, int numDevices, int p, int q, bool bUsePBO, bool useHostMem, bool useCpu) { if (useCpu) { m_nbodyCpu = new BodySystemCPU<T>(numBodies); m_nbody = m_nbodyCpu; m_nbodyCuda = 0; } else { m_nbodyCuda = new BodySystemCUDA<T>(numBodies, numDevices, p, q, bUsePBO, useHostMem); m_nbody = m_nbodyCuda; m_nbodyCpu = 0; } // allocate host memory m_hPos = new T[numBodies*4]; m_hVel = new T[numBodies*4]; m_hColor = new float[numBodies*4]; m_nbody->setSoftening(activeParams.m_softening); m_nbody->setDamping(activeParams.m_damping); if (useCpu) { sdkCreateTimer(&timer); sdkStartTimer(&timer); } else { checkCudaErrors(cudaEventCreate(&startEvent)); checkCudaErrors(cudaEventCreate(&stopEvent)); checkCudaErrors(cudaEventCreate(&hostMemSyncEvent)); } if (!benchmark && !compareToCPU) { m_renderer = new ParticleRenderer; _resetRenderer(); } sdkCreateTimer(&demoTimer); sdkStartTimer(&demoTimer); }
void _resetRenderer() { if (fp64) { float color[4] = { 0.4f, 0.8f, 0.1f, 1.0f}; m_renderer->setBaseColor(color); } else { float color[4] = { 1.0f, 0.6f, 0.3f, 1.0f}; m_renderer->setBaseColor(color); } m_renderer->setColors(m_hColor, m_nbody->getNumBodies()); m_renderer->setSpriteSize(activeParams.m_pointSize); }