35 #define PARALLEL_PLAN_MOVE
36 #define PARALLEL_EXEC_MOVE
47 myLanes(
MSLane::dictSize()),
48 myWithVehicles2Integrate(
MSGlobals::gNumSimThreads > 1),
49 myLastLaneChange(
MSEdge::dictSize()),
50 myInactiveCheckCollisions(
MSGlobals::gNumSimThreads > 1),
51 myMinLengthGeometryFactor(1.),
53 myThreadPool(false, std::vector<int>(
MSGlobals::gNumThreads, 0)),
58 const std::vector<MSLane*>& lanes = edge->getLanes();
59 if (!edge->hasLaneChanger()) {
60 const int pos = lanes.front()->getNumericalID();
61 myLanes[pos].lane = lanes.front();
63 myLanes[pos].haveNeighbors =
false;
66 for (
MSLane*
const l : lanes) {
67 const int pos = l->getNumericalID();
70 myLanes[pos].haveNeighbors =
true;
80 new WorkerThread(myThreadPool);
94 #ifdef PARALLEL_STOPWATCH
97 for (
MSLane*
const l : edge->getLanes()) {
98 wPlan.
add(l->getStopWatch()[0]);
101 std::cout << wPlan.
getHistory().size() <<
" lane planmove calls, average " << wPlan.
getAverage() <<
" ns, total " << wPlan.
getTotal() / double(1e9) <<
" s" << std::endl;
102 std::cout <<
myStopWatch[0].getHistory().size() <<
" planmove calls, average " <<
myStopWatch[0].getAverage() <<
" ns, total " <<
myStopWatch[0].getTotal() / double(1e9) <<
" s" << std::endl;
103 std::cout <<
myStopWatch[1].getHistory().size() <<
" execmove calls, average " <<
myStopWatch[1].getAverage() <<
" ns, total " <<
myStopWatch[1].getTotal() / double(1e9) <<
" s" << std::endl;
113 if (!lu.
amActive && (*i)->getVehicleNumber() > 0) {
129 #ifdef PARALLEL_STOPWATCH
133 std::vector<std::future<void>> results;
136 const int vehNum = (*i)->getVehicleNumber();
138 myLanes[(*i)->getNumericalID()].amActive =
false;
143 results.push_back(myThreadPool.executeAsync([i, t](
int) {
144 (*i)->planMovements(t);
152 myThreadPool.add((*i)->getPlanMoveTask(t), (*i)->getRNGIndex() % myThreadPool.size());
158 (*i)->planMovements(t);
163 for (
auto& r : results) {
169 myThreadPool.waitAll(
false);
173 #ifdef PARALLEL_STOPWATCH
182 lane->setJunctionApproaches(t);
189 #ifdef PARALLEL_STOPWATCH
194 #ifdef PARALLEL_EXEC_MOVE
198 myThreadPool.executeAsync([lane, t](
int) {
199 lane->executeMovements(t);
202 myThreadPool.waitAll();
208 myThreadPool.add(lane->getExecuteMoveTask(t), lane->getRNGIndex() % myThreadPool.size());
210 myThreadPool.waitAll(
false);
220 (*i)->getVehicleNumber() > 0) {
221 (*i)->executeMovements(t);
223 if ((*i)->getVehicleNumber() == 0) {
224 myLanes[(*i)->getNumericalID()].amActive =
false;
230 for (
MSLane* lane : wasActive) {
231 lane->updateLengthSum();
240 for (
MSLane*
const lane : toIntegrate) {
241 const bool wasInactive = lane->getVehicleNumber() == 0;
242 lane->integrateNewVehicles();
243 if (wasInactive && lane->getVehicleNumber() > 0) {
255 #ifdef PARALLEL_STOPWATCH
263 std::vector<MSLane*> toAdd;
264 #ifdef PARALLEL_CHANGE_LANES
265 std::vector<const MSEdge*> recheckLaneUsage;
269 if (
myLanes[l->getNumericalID()].haveNeighbors) {
270 const MSEdge& edge = l->getEdge();
273 #ifdef PARALLEL_CHANGE_LANES
276 myThreadPool.add(lane->getLaneChangeTask(t), lane->
getRNGIndex() % myThreadPool.size());
277 recheckLaneUsage.push_back(&edge);
287 if (lane->getVehicleNumber() > 0 && !lu.
amActive) {
288 toAdd.push_back(lane);
292 lane->sortManeuverReservations();
295 #ifdef PARALLEL_CHANGE_LANES
304 #ifdef PARALLEL_CHANGE_LANES
306 myThreadPool.waitAll(
false);
307 for (
const MSEdge* e : recheckLaneUsage) {
308 for (
MSLane*
const l : e->getLanes()) {
310 if (l->getVehicleNumber() > 0 && !lu.
amActive) {
315 l->sortManeuverReservations();
323 for (std::vector<MSLane*>::iterator i = toAdd.begin(); i != toAdd.end(); ++i) {
333 if (lane->needsCollisionCheck()) {
334 lane->detectCollisions(timestep, stage);
339 lane->detectCollisions(timestep, stage);
361 const std::vector<MSLane*>& lanes = e->getLanes();
362 for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
363 (*j)->initRestrictions();
371 edge->updateMesoType();
#define PARALLEL_EXEC_MOVE
Container & getContainer()
Container & getContainer()
void patchActiveLanes()
Resets information whether a lane is active for all lanes.
std::vector< StopWatch< std::chrono::nanoseconds > > myStopWatch
~MSEdgeControl()
Destructor.
void setMesoTypes()
update meso edge type parameters
void setAdditionalRestrictions()
apply additional restrictions
FXSynchSet< MSLane *, std::set< MSLane *, ComparatorNumericalIdLess > > myInactiveCheckCollisions
Additional lanes for which collision checking must be performed.
std::list< MSLane * > myActiveLanes
The list of active (not empty) lanes.
void detectCollisions(SUMOTime timestep, const std::string &stage)
Detect collisions.
MSEdgeVector myEdges
Loaded edges.
void setJunctionApproaches(SUMOTime t)
Register junction approaches for all vehicles after velocities have been planned. This is a prerequis...
void executeMovements(SUMOTime t)
Executes planned vehicle movements with regards to right-of-way.
LaneUsageVector myLanes
Information about lanes' number of vehicles and neighbors.
void gotActive(MSLane *l)
Informs the control that the given lane got active.
void checkCollisionForInactive(MSLane *l)
trigger collision checking for inactive lane
std::vector< SUMOTime > myLastLaneChange
The list of active (not empty) lanes.
std::set< MSLane *, ComparatorNumericalIdLess > myChangedStateLanes
Lanes which changed the state without informing the control.
void planMovements(SUMOTime t)
Compute safe velocities for all vehicles based on positions and speeds from the last time step....
FXSynchQue< MSLane *, std::vector< MSLane * > > myWithVehicles2Integrate
A storage for lanes which shall be integrated because vehicles have moved onto them.
void changeLanes(const SUMOTime t)
Moves (precomputes) critical vehicles.
MSEdgeControl(const std::vector< MSEdge * > &edges)
Constructor.
double myMinLengthGeometryFactor
A road/street connecting two junctions.
void changeLanes(SUMOTime t) const
Performs lane changing on this edge.
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
int getNumericalID() const
Returns the numerical id of the edge.
static double gLateralResolution
static bool gComputeLC
whether the simulationLoop is in the lane changing phase
static int gNumSimThreads
how many threads to use for simulation
static int gNumThreads
how many threads to use
Representation of a lane in the micro simulation.
int getRNGIndex() const
returns the associated RNG index
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
void removePending()
Removes a vehicle after it has ended.
const std::vector< TimeT > & getHistory() const
long long int getTotal() const
long long int getAverage() const
void add(const StopWatch< TimeT, ClockT > &other)
Function-object for stable sorting of objects acting like Named without being derived (SUMOVehicle)
A structure holding some basic information about a simulated lane.
bool amActive
Information whether this lane is active.
bool haveNeighbors
Information whether this lane belongs to a multi-lane edge.