Fflcun2::ParticlesPosition Fflcun2::run(int nSteps) { for(int j = 0; j < nSteps; j++) { runCalcU(blocks, threads, devMatrixes); cudaThreadSynchronize(); if (cPar->ft == ConstParams::ROTATING) { chPar->hExtX = cPar->hExtXInit * sin(2 * M_PI * cPar->rff * chPar->time); chPar->hExtY = cPar->hExtYInit * cos(2 * M_PI * cPar->rff * chPar->time); } fillGloabalChangable(chPar); cudaThreadSynchronize(); runOneStep(blocks, threads, devMatrixes); cudaThreadSynchronize(); runApplyDeltas(blocks, threads, devMatrixes); cudaThreadSynchronize(); chPar->time += chPar->dTimeCurrent; } /* cudaMemcpy(partPos.x, devMatrixes.x, sizeof(float) * cPar->nPart, cudaMemcpyDeviceToHost); cudaMemcpy(partPos.y, devMatrixes.y, sizeof(float) * cPar->nPart, cudaMemcpyDeviceToHost); cudaMemcpy(partPos.z, devMatrixes.z, sizeof(float) * cPar->nPart, cudaMemcpyDeviceToHost); cudaMemcpy(partPos.theta, devMatrixes.theta, sizeof(float) * cPar->nPart, cudaMemcpyDeviceToHost); cudaMemcpy(partPos.phy, devMatrixes.phy, sizeof(float) * cPar->nPart, cudaMemcpyDeviceToHost); */ cudaMemcpy(partPos.x, devMatrixes.x, sizeof(float) * cPar->nPart, cudaMemcpyDeviceToHost); cudaMemcpy(partPos.y, devMatrixes.y, sizeof(float) * cPar->nPart, cudaMemcpyDeviceToHost); cudaMemcpy(partPos.z, devMatrixes.z, sizeof(float) * cPar->nPart, cudaMemcpyDeviceToHost); cudaMemcpy(partPos.theta, devMatrixes.theta, sizeof(float) * cPar->nPart, cudaMemcpyDeviceToHost); cudaMemcpy(partPos.phy, devMatrixes.phy, sizeof(float) * cPar->nPart, cudaMemcpyDeviceToHost); return partPos; }
/** * Begin the simulation. */ void startSimulation() { uint32_t currentStep = init(); tInit.toggleEnd(); if (output) { std::cout << "initialization time: " << tInit.printInterval() << " = " << (int) (tInit.getInterval() / 1000.) << " sec" << std::endl; } TimeIntervall tSimCalculation; TimeIntervall tRound; double roundAvg = 0.0; /* dump initial step if simulation starts without restart */ if (currentStep == 0) dumpOneStep(currentStep); else currentStep--; //we dump before calculation, thus we must go on step back if we do a restart movingWindowCheck(currentStep); //if we restart at any step check if we must slide /* dump 0% output */ dumpTimes(tSimCalculation, tRound, roundAvg, currentStep); while (currentStep < runSteps) { tRound.toggleStart(); runOneStep(currentStep); tRound.toggleEnd(); roundAvg += tRound.getInterval(); currentStep++; /*output after a round*/ dumpTimes(tSimCalculation, tRound, roundAvg, currentStep); movingWindowCheck(currentStep); /*dump after simulated step*/ dumpOneStep(currentStep); } //simulatation end Environment<>::get().Manager().waitForAllTasks(); tSimCalculation.toggleEnd(); if (output) { std::cout << "calculation simulation time: " << tSimCalculation.printInterval() << " = " << (int) (tSimCalculation.getInterval() / 1000.) << " sec" << std::endl; } }
// This member function decorates the situation updater as a normal function, // thus hiding the possible separate thread behind to the main updater. void ReSituationUpdater::computeCurrentStep() { // Nothing to do if actually threaded : // the updater thread is already doing the job on his side. if (_bThreaded) return; // Non-threaded mode. GfProfStartProfile("reOneStep*"); tRmInfo* pCurrReInfo = ReSituation::self().data(); // Stable but slowed-down frame rate mode. if (_fOutputTick > 0) { while ((pCurrReInfo->_reCurTime - _fLastOutputTime) < _fOutputTick) runOneStep(_fSimuTick); _fLastOutputTime = pCurrReInfo->_reCurTime; } // Real-time but variable frame rate mode. else { const double t = GfTimeClock(); while (pCurrReInfo->_reRunning && ((t - pCurrReInfo->_reCurTime) > RCM_MAX_DT_SIMU)) runOneStep(_fSimuTick); } GfProfStopProfile("reOneStep*"); // Send car physics to network if needed if (NetGetNetwork()) NetGetNetwork()->SendCarControlsPacket(pCurrReInfo->s); }
/** * Begin the simulation. */ void startSimulation() { init(); // translate checkpointPeriod string into checkpoint intervals seqCheckpointPeriod = pluginSystem::toTimeSlice( checkpointPeriod ); for (uint32_t nthSoftRestart = 0; nthSoftRestart <= softRestarts; ++nthSoftRestart) { resetAll(0); uint32_t currentStep = fillSimulation(); Environment<>::get().SimulationDescription().setCurrentStep( currentStep ); tInit.toggleEnd(); if (output) { std::cout << "initialization time: " << tInit.printInterval() << " = " << (int) (tInit.getInterval() / 1000.) << " sec" << std::endl; } TimeIntervall tSimCalculation; TimeIntervall tRound; double roundAvg = 0.0; /* Since in the main loop movingWindow is called always before the dump, we also call it here for consistency. * This becomes only important, if movingWindowCheck does more than merely checking for a slide. * TO DO in a new feature: Turn this into a general hook for pre-checks (window slides are just one possible action). */ movingWindowCheck(currentStep); /* dump initial step if simulation starts without restart */ if (!restartRequested) { dumpOneStep(currentStep); } /* dump 0% output */ dumpTimes(tSimCalculation, tRound, roundAvg, currentStep); /** \todo currently we assume this is the only point in the simulation * that is allowed to manipulate `currentStep`. Else, one needs to * add and act on changed values via * `SimulationDescription().getCurrentStep()` in this loop */ while (currentStep < Environment<>::get().SimulationDescription().getRunSteps()) { tRound.toggleStart(); runOneStep(currentStep); tRound.toggleEnd(); roundAvg += tRound.getInterval(); /* NEXT TIMESTEP STARTS HERE */ currentStep++; Environment<>::get().SimulationDescription().setCurrentStep( currentStep ); /* output times after a round */ dumpTimes(tSimCalculation, tRound, roundAvg, currentStep); movingWindowCheck(currentStep); /* dump at the beginning of the simulated step */ dumpOneStep(currentStep); } // simulatation end Environment<>::get().Manager().waitForAllTasks(); tSimCalculation.toggleEnd(); if (output) { std::cout << "calculation simulation time: " << tSimCalculation.printInterval() << " = " << (int) (tSimCalculation.getInterval() / 1000.) << " sec" << std::endl; } } // softRestarts loop }
int ReSituationUpdater::threadLoop() { // Wait delay for each loop, from bRunning value (index 0 = false, 1 = true). static const unsigned KWaitDelayMS[2] = { 1, (unsigned)(RCM_MAX_DT_SIMU * 1000 / 10) }; // Termination flag. bool bEnd = false; // Local state (false = paused, true = simulating). bool bRunning = false; // Current real time. double realTime; // Apply thread affinity to the current = situation updater thread if specified. // Note: No need to reset the affinity, as the thread is just born. if (_bThreadAffinity) GfSetThreadAffinity(NSituationUpdaterCPUId); tRmInfo* pCurrReInfo = ReSituation::self().data(); GfLogInfo("SituationUpdater thread is started.\n"); do { // Let's make current step the next one (update). // 1) Lock the race engine data. ReSituation::self().lock("ReSituationUpdater::threadLoop"); // 2) Check if time to terminate has come. if (_bTerminate) bEnd = true; // 3) If not time to terminate, and running, do the update job. else if (pCurrReInfo->_reRunning) { if (!bRunning) { bRunning = true; GfLogInfo("SituationUpdater thread is running.\n"); } realTime = GfTimeClock(); GfProfStartProfile("reOneStep*"); while (pCurrReInfo->_reRunning && ((realTime - pCurrReInfo->_reCurTime) > RCM_MAX_DT_SIMU)) { // One simu + robots (if any) step runOneStep(RCM_MAX_DT_SIMU); } GfProfStopProfile("reOneStep*"); // Send car physics to network if needed if (NetGetNetwork()) NetGetNetwork()->SendCarControlsPacket(pCurrReInfo->s); } // 3) If not time to terminate, and not running, do nothing. else { if (bRunning) { bRunning = false; GfLogInfo("SituationUpdater thread is paused.\n"); } } // 4) Unlock the race engine data. ReSituation::self().unlock("ReSituationUpdater::threadLoop"); // 5) Let the CPU take breath if possible (but after unlocking data !). SDL_Delay(KWaitDelayMS[(int)bRunning]); } while (!bEnd); GfLogInfo("SituationUpdater thread has been terminated.\n"); return 0; }