-
Notifications
You must be signed in to change notification settings - Fork 698
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use distance threshold in hierarchy limits for bidir-astar #3156
Conversation
Unfortunately, this change causes performance degradation. There are timings:
branch
We can see that in average timings increased by ~15%. The good news that for long routes (more important metric) it's only ~10% increase. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the performance impact of computing 2 additional distances? The use of counts rather than distance was done for performance reasons and also to allow the hierarchies to work in both dense and sparse environments.
In dense environments one generally has to travel less distance to move up to the next hierarchy - counting upward hierarchy transitions ensures enough candidates are found. Similarly in rural environments one has to generally travel further to ensure enough transitions onto higher class roads are made.
37208f7
to
fbd8f24
Compare
@@ -85,7 +85,7 @@ def make_request(post_body): | |||
parser.add_argument('--output-dir', type=str, help='The directory in which to place the result of each request') | |||
parser.add_argument('--concurrency', type=int, help='The number of processes to use to make requests', default=multiprocessing.cpu_count()) | |||
parser.add_argument('--format', type=str, help='Supports csv, json, raw and null output formats', default='csv') | |||
parser.add_argument('--headers', type=str, help='Additional http headers to send with the requests. Follows the http header spec, eg. some-header-name: some-header-value', action='append', nargs='*') | |||
parser.add_argument('--headers', type=str, help='Additional http headers to send with the requests. Follows the http header spec, eg. some-header-name: some-header-value', action='append', nargs='*', default=[]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this script failed if --headers
parameter wasn't specified. adding default value fixes it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strange! i swore i tested that... thank you for cleaning it up!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mandeepsandhu this is where you saw that
src/thor/bidirectional_astar.cc
Outdated
// they can be lowered. | ||
// Decrease distance thresholds only for arterial roads for now | ||
hierarchy_limits_forward_[1].expansion_within_dist /= 5.f; | ||
hierarchy_limits_reverse_[1].expansion_within_dist /= 5.f; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
current default hierarchy limit for arterial roads is 100km; it's very costly for performance. This code decreases it to 20km making performance drop more or less reasonable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i guess we have to do a big round of RAD to see what kind of changes we get though. I could imagine many routes will change because of this especially in rural areas where now you have to find an upward transition within 20km.
with respect to the performance difference how many routes are run with a retry and relaxed limits vs master? i wonder if we would have more retries with this change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i guess we have to do a big round of RAD to see what kind of changes we get though. I could imagine many routes will change because of this especially in rural areas where now you have to find an upward transition within 20km.
agree about RAD. I'm working on it right now
with respect to the performance difference how many routes are run with a retry and relaxed limits vs master? i wonder if we would have more retries with this change
interesting note. I will check it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kevinkreiser about retries: it's approximately the same: 296 (master) vs 292 (branch)
I didn't check it, but I think it's unnoticeable.
I agree with that. But for some cases in dense environments we exhaust transition count limit too fast (look at the example in the issue #3075 , the local road we skipped is very close to the destination point but the limits were exhausted before we got it). So, my point here is the following: |
You probably don't need absolute distance - rather you perhaps could avoid sqrt calls for these 2 by using distance squared and configuring the hierarchy distances to be squared distance. Maybe do a performance comparison between using GetDistance and GetDistanceSquared (I think you need a new method in astarheuristic.h). I just remember through the years doing a lot of work to avoid sqrt calls as much as possible. |
Also, is there a way to avoid computing these distances for modes that do not use hierarchies (pedestrian, bicycle)? I just did a comparison with bicycle routes and noted a 6.7% drop in performance with no change in the route and no change in the number of EdgeLabels added. So this PR drops bicycle routing performance significantly with no impact to the actual route computation. I think this is almost entirely due to the cost of the new GetDistance calls - there may be a slight cost to propogate into EdgeLabel but otherwise there is no change. |
how did you test performance for bicycles ? did you generate some random routes or use from |
I test a single, long bicycle route that I have tracked performance on for several years. I use valhalla_run_route with multi-run set to 100. This will then average the PathAlgorithm time over 100 successive calls (ignores the first to make sure all data is in cache). Obviosuly this doesn't cover a wide range of conditions (e.g. road densities, etc.) but it fully stresses just the PathAlgorithm - there is no I/O and CPU is 100% for the one thread computing the route. I also did this for auto routes while at Mapzen and Mapbox so that I could track performance of a known route over time - comparing code changes and data set changes. The command is: ./valhalla_run_route --config ../../conf/planetv14.json --multi-run 100 -j '{"locations":[{"lat":39.64225,"lon":-76.10536,"type":"break"},{"lat":38.899677,"lon":-77.050916,"type":"break"}],"costing":"bicycle","costing_options":{"bicycle":{"bicycle_type":"Road","use_roads":"0.0","cycling_speed":"25.0","use_hills":"0.5"}}}' | grep GetBestPath |
Thank you! will try the same. hm, I'm getting not very stable results with a such test. variance is about 10%. Instead of that I created |
I always reboot my laptop (so all other apps are stopped) and make sure no browsers are open prior to running this benchmark. When I do that I get very good consistency between results (usually only vary by a couple ms for the request). |
did the same. So, results became more stable, but less than using
branch
It's almost the same, but I agree that we can avoid distance calculation for cases when hierarchy limits are disabled (bicycle and pedestrian). |
@dnesbitt61 @kevinkreiser I've finished with RAD tests. I ran locally (with my local planet) ~14000 requests for Most significant improvements in ETA were achieved on routes that include ferries or country crossing (I suspect because near ferries or country borders lie lower level edges that were covered by the branch and missed by master). Each route with downgraded ETA can be explained in one of the following ways: ETA is bigger but the route cost is smaller.It turned out that for some routes cost were improved but ETA not. As far as our actual score is cost, we can treat such routes as improved. Bidirectional astar stops iterating too early.This is well known problem #2928. For some routes, when I temporary fixed cost threshold in the branch (or even enabled alternatives that extend cost threshold) I got the same routes as in master. Inaccurate shortcut's costs.Cost for some shortcuts may be slightly different from the sum of costs of superseded edges. Due to the changes in hierarchy limits logic some shortcuts may be still unavailable in branch (https://github.com/valhalla/valhalla/blob/master/src/thor/bidirectional_astar.cc#L166) because they lie too close to the origin/destination point but may be used in master. In some cases it may lead to different optimal routes. Hierarchy limits + multiple starting edges.We initialize forward/reverse search with different starting edges. For each edge we calculate initial cost (equal to squared distance from the origin/destination point to the edge). In some cases initial cost can be very big. It may lead to a very unbalanced search and a situation when we complete a route before exhaust hierarchy limits. So, we can miss local optimality near the origin/destination point. I think this is a separate issue that shouldn't be fixed in this PR. |
@kevinkreiser do you know why prime_server build is failing on osx ? https://app.circleci.com/pipelines/github/valhalla/valhalla/7155/workflows/bf03b7a0-942a-4b47-9e1b-800458f85419/jobs/44939 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks fine to me but I can only really test bicycle routing. No performance difference in my use case. I don't create data with hierarchies so that was expected/desired.
thanks! |
I know what you mean by this problem but are you saying that this happens more frequently with this branch? I am missing the bigger point about what you were seeing with respect to this problem in the branch. Can you maybe reiterate?
That one is a long standing problem. Its very hard to tune the penalty to make sense. Originally i had it set to be walking speed cost of straight line distance to the snap point but this was sometimes not enough penalty. That is why we have options to disable the penality (which is a bandaid but at least it gives the option). |
I don't say that for this branch it happens more frequently. I just analyzed downgraded routes and for some of them it was a reason. That's expected to me. |
As for me, it worth a separate issue. And, actually there are 2 problems here:
|
@kevinkreiser did I answer your question? Or some more clarifications are needed ? |
Issue
This PR partially solves the problem described here #3075 . It fixes cases when an important road with low FRC is near the destination/origin point but can be skipped due to hierarchy limits logic. Especially it may happen for cases when the destination/origin point is situated in a dense places (like city center). Intuition says that in order to be guaranteed to find important roads with low FRC we should always allow expansion within some radius (same logic as for unidirectional search).
Tasklist
Requirements / Relations
Link any requirements here. Other pull requests this PR is based on?