mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 07:25:47 +03:00
Be smarter with LTN impact prediction memory usage.
... but this doesn't actually fix the mysterious crash in Camden and other maps?!
This commit is contained in:
parent
bc97ed2d3a
commit
b6b69aa886
@ -4,7 +4,9 @@ use abstio::MapName;
|
|||||||
use abstutil::{prettyprint_usize, Counter, Timer};
|
use abstutil::{prettyprint_usize, Counter, Timer};
|
||||||
use geom::{Distance, Histogram, Statistic};
|
use geom::{Distance, Histogram, Statistic};
|
||||||
use map_gui::tools::{cmp_count, ColorScale, DivergingScale};
|
use map_gui::tools::{cmp_count, ColorScale, DivergingScale};
|
||||||
use map_model::{IntersectionID, Map, PathRequest, PathStepV2, PathfinderCaching, RoadID};
|
use map_model::{
|
||||||
|
IntersectionID, Map, PathRequest, PathStepV2, PathfinderCaching, RoadID, RoutingParams,
|
||||||
|
};
|
||||||
use sim::{Scenario, TripEndpoint, TripMode};
|
use sim::{Scenario, TripEndpoint, TripMode};
|
||||||
use widgetry::mapspace::{ObjectID, World};
|
use widgetry::mapspace::{ObjectID, World};
|
||||||
use widgetry::{Color, EventCtx, Line, Text};
|
use widgetry::{Color, EventCtx, Line, Text};
|
||||||
@ -85,30 +87,16 @@ impl Results {
|
|||||||
|
|
||||||
// Before the filters. These don't change with no filters, so only calculate once per map
|
// Before the filters. These don't change with no filters, so only calculate once per map
|
||||||
if self.before_road_counts.is_empty() {
|
if self.before_road_counts.is_empty() {
|
||||||
self.before_road_counts = Counter::new();
|
let (roads, intersections) = count_throughput(
|
||||||
self.before_intersection_counts = Counter::new();
|
&self.all_driving_trips,
|
||||||
for path in timer
|
map,
|
||||||
.parallelize(
|
map.routing_params().clone(),
|
||||||
"calculate routes before filters",
|
PathfinderCaching::NoCache,
|
||||||
self.all_driving_trips.clone(),
|
timer,
|
||||||
|req| map.pathfind_v2(req),
|
);
|
||||||
)
|
self.before_road_counts = roads;
|
||||||
.into_iter()
|
self.before_intersection_counts = intersections;
|
||||||
.flatten()
|
|
||||||
{
|
|
||||||
for step in path.get_steps() {
|
|
||||||
// No Contraflow steps for driving paths
|
|
||||||
match step {
|
|
||||||
PathStepV2::Along(dr) => {
|
|
||||||
self.before_road_counts.inc(dr.road);
|
|
||||||
}
|
|
||||||
PathStepV2::Movement(m) => {
|
|
||||||
self.before_intersection_counts.inc(m.parent);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.before_world = make_world(ctx, app);
|
self.before_world = make_world(ctx, app);
|
||||||
ranked_roads(
|
ranked_roads(
|
||||||
ctx,
|
ctx,
|
||||||
@ -127,47 +115,37 @@ impl Results {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// After the filters
|
// After the filters
|
||||||
self.after_road_counts = Counter::new();
|
|
||||||
self.after_intersection_counts = Counter::new();
|
|
||||||
let mut params = map.routing_params().clone();
|
|
||||||
app.session.modal_filters.update_routing_params(&mut params);
|
|
||||||
for path in timer
|
|
||||||
.parallelize(
|
|
||||||
"calculate routes after filters",
|
|
||||||
self.all_driving_trips.clone(),
|
|
||||||
|req| map.pathfind_v2_with_params(req, ¶ms, PathfinderCaching::CacheDijkstra),
|
|
||||||
)
|
|
||||||
.into_iter()
|
|
||||||
.flatten()
|
|
||||||
{
|
{
|
||||||
for step in path.get_steps() {
|
let mut params = map.routing_params().clone();
|
||||||
// No Contraflow steps for driving paths
|
app.session.modal_filters.update_routing_params(&mut params);
|
||||||
match step {
|
// Since we're making so many requests, it's worth it to rebuild a contraction
|
||||||
PathStepV2::Along(dr) => {
|
// hierarchy. And since we're single-threaded, no complications there.
|
||||||
self.after_road_counts.inc(dr.road);
|
let (roads, intersections) = count_throughput(
|
||||||
}
|
&self.all_driving_trips,
|
||||||
PathStepV2::Movement(m) => {
|
map,
|
||||||
self.after_intersection_counts.inc(m.parent);
|
params,
|
||||||
}
|
PathfinderCaching::CacheCH,
|
||||||
_ => {}
|
timer,
|
||||||
}
|
);
|
||||||
}
|
self.after_road_counts = roads;
|
||||||
|
self.after_intersection_counts = intersections;
|
||||||
|
|
||||||
|
self.after_world = make_world(ctx, app);
|
||||||
|
ranked_roads(
|
||||||
|
ctx,
|
||||||
|
map,
|
||||||
|
&mut self.after_world,
|
||||||
|
&self.after_road_counts,
|
||||||
|
&app.cs.good_to_bad_red,
|
||||||
|
);
|
||||||
|
ranked_intersections(
|
||||||
|
ctx,
|
||||||
|
map,
|
||||||
|
&mut self.after_world,
|
||||||
|
&self.after_intersection_counts,
|
||||||
|
&app.cs.good_to_bad_red,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
self.after_world = make_world(ctx, app);
|
|
||||||
ranked_roads(
|
|
||||||
ctx,
|
|
||||||
map,
|
|
||||||
&mut self.after_world,
|
|
||||||
&self.after_road_counts,
|
|
||||||
&app.cs.good_to_bad_red,
|
|
||||||
);
|
|
||||||
ranked_intersections(
|
|
||||||
ctx,
|
|
||||||
map,
|
|
||||||
&mut self.after_world,
|
|
||||||
&self.after_intersection_counts,
|
|
||||||
&app.cs.good_to_bad_red,
|
|
||||||
);
|
|
||||||
|
|
||||||
self.recalculate_relative_diff(ctx, app);
|
self.recalculate_relative_diff(ctx, app);
|
||||||
}
|
}
|
||||||
@ -297,3 +275,42 @@ fn ranked_intersections(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn count_throughput(
|
||||||
|
requests: &[PathRequest],
|
||||||
|
map: &Map,
|
||||||
|
params: RoutingParams,
|
||||||
|
cache_custom: PathfinderCaching,
|
||||||
|
timer: &mut Timer,
|
||||||
|
) -> (Counter<RoadID>, Counter<IntersectionID>) {
|
||||||
|
let mut road_counts = Counter::new();
|
||||||
|
let mut intersection_counts = Counter::new();
|
||||||
|
|
||||||
|
// It's very memory intensive to calculate all of the paths in one chunk, then process them to
|
||||||
|
// get counts. Increment the counters as we go.
|
||||||
|
//
|
||||||
|
// TODO But that makes it hard to use timer.parallelize for this. We could make a thread-local
|
||||||
|
// Counter and aggregte them at the end, but the way timer.parallelize uses scoped_threadpool
|
||||||
|
// right now won't let that work. Stick to single-threaded for now.
|
||||||
|
|
||||||
|
timer.start_iter("calculate routes", requests.len());
|
||||||
|
for req in requests {
|
||||||
|
timer.next();
|
||||||
|
if let Ok(path) = map.pathfind_v2_with_params(req.clone(), ¶ms, cache_custom) {
|
||||||
|
for step in path.get_steps() {
|
||||||
|
// No Contraflow steps for driving paths
|
||||||
|
match step {
|
||||||
|
PathStepV2::Along(dr) => {
|
||||||
|
road_counts.inc(dr.road);
|
||||||
|
}
|
||||||
|
PathStepV2::Movement(m) => {
|
||||||
|
intersection_counts.inc(m.parent);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(road_counts, intersection_counts)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user