Use Intel TBB's parallel_sort even for nested parallelism.
TBB has a global task scheduler (that's one of the reason TBB is not
linked statically but dyanmically instead). This allows control over all
running threads, enabling us to use nested parallelism and the scheduler
doing all the task allocation itself.
That is, nested parallel execution such as in
parallel_for(seq, [](const auto& rng){
parallel_sort(rng);
});
is no problem at all, as the scheduler still claims control over the
global environment.
Therefore, use `parallel_sort` Range overload where possible.
References:
- https://www.threadingbuildingblocks.org/docs/help/hh_goto.htm#reference/algorithms.htm
- https://www.threadingbuildingblocks.org/docs/help/hh_goto.htm#reference/algorithms/parallel_sort_func.htm
- https://www.threadingbuildingblocks.org/docs/help/hh_goto.htm#reference/task_scheduler.htm
- https://www.threadingbuildingblocks.org/docs/help/hh_goto.htm#reference/task_scheduler/task_scheduler_init_cls.htm
- https://www.threadingbuildingblocks.org/docs/help/hh_goto.htm#tbb_userguide/Initializing_and_Terminating_the_Library.htm
This commit is contained in:
+28
-18
@@ -42,6 +42,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "../util/json_util.hpp"
|
||||
#include "../util/string_util.hpp"
|
||||
|
||||
#include <tbb/parallel_sort.h>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -97,7 +99,8 @@ template <class DataFacadeT> class MapMatchingPlugin : public BasePlugin
|
||||
osrm::matching::CandidateLists &candidates_lists)
|
||||
{
|
||||
double query_radius = 10 * gps_precision;
|
||||
double last_distance = coordinate_calculation::great_circle_distance(input_coords[0], input_coords[1]);
|
||||
double last_distance =
|
||||
coordinate_calculation::great_circle_distance(input_coords[0], input_coords[1]);
|
||||
|
||||
sub_trace_lengths.resize(input_coords.size());
|
||||
sub_trace_lengths[0] = 0;
|
||||
@@ -106,7 +109,8 @@ template <class DataFacadeT> class MapMatchingPlugin : public BasePlugin
|
||||
bool allow_uturn = false;
|
||||
if (0 < current_coordinate)
|
||||
{
|
||||
last_distance = coordinate_calculation::great_circle_distance(input_coords[current_coordinate - 1], input_coords[current_coordinate]);
|
||||
last_distance = coordinate_calculation::great_circle_distance(
|
||||
input_coords[current_coordinate - 1], input_coords[current_coordinate]);
|
||||
|
||||
sub_trace_lengths[current_coordinate] +=
|
||||
sub_trace_lengths[current_coordinate - 1] + last_distance;
|
||||
@@ -127,20 +131,24 @@ template <class DataFacadeT> class MapMatchingPlugin : public BasePlugin
|
||||
|
||||
std::vector<std::pair<PhantomNode, double>> candidates;
|
||||
facade->IncrementalFindPhantomNodeForCoordinateWithMaxDistance(
|
||||
input_coords[current_coordinate], candidates, query_radius);
|
||||
input_coords[current_coordinate], candidates, query_radius);
|
||||
|
||||
// sort by foward id, then by reverse id and then by distance
|
||||
std::sort(candidates.begin(), candidates.end(),
|
||||
[](const std::pair<PhantomNode, double>& lhs, const std::pair<PhantomNode, double>& rhs) {
|
||||
tbb::parallel_sort(
|
||||
candidates, [](const std::pair<PhantomNode, double> &lhs,
|
||||
const std::pair<PhantomNode, double> &rhs)
|
||||
{
|
||||
return lhs.first.forward_node_id < rhs.first.forward_node_id ||
|
||||
(lhs.first.forward_node_id == rhs.first.forward_node_id &&
|
||||
(lhs.first.reverse_node_id < rhs.first.reverse_node_id ||
|
||||
(lhs.first.reverse_node_id == rhs.first.reverse_node_id &&
|
||||
lhs.second < rhs.second)));
|
||||
(lhs.first.forward_node_id == rhs.first.forward_node_id &&
|
||||
(lhs.first.reverse_node_id < rhs.first.reverse_node_id ||
|
||||
(lhs.first.reverse_node_id == rhs.first.reverse_node_id &&
|
||||
lhs.second < rhs.second)));
|
||||
});
|
||||
|
||||
auto new_end = std::unique(candidates.begin(), candidates.end(),
|
||||
[](const std::pair<PhantomNode, double>& lhs, const std::pair<PhantomNode, double>& rhs) {
|
||||
auto new_end = std::unique(
|
||||
candidates.begin(), candidates.end(), [](const std::pair<PhantomNode, double> &lhs,
|
||||
const std::pair<PhantomNode, double> &rhs)
|
||||
{
|
||||
return lhs.first.forward_node_id == rhs.first.forward_node_id &&
|
||||
lhs.first.reverse_node_id == rhs.first.reverse_node_id;
|
||||
});
|
||||
@@ -165,10 +173,11 @@ template <class DataFacadeT> class MapMatchingPlugin : public BasePlugin
|
||||
}
|
||||
|
||||
// sort by distance to make pruning effective
|
||||
std::sort(candidates.begin(), candidates.end(),
|
||||
[](const std::pair<PhantomNode, double>& lhs, const std::pair<PhantomNode, double>& rhs) {
|
||||
return lhs.second < rhs.second;
|
||||
});
|
||||
tbb::parallel_sort(candidates, [](const std::pair<PhantomNode, double> &lhs,
|
||||
const std::pair<PhantomNode, double> &rhs)
|
||||
{
|
||||
return lhs.second < rhs.second;
|
||||
});
|
||||
|
||||
candidates_lists.push_back(std::move(candidates));
|
||||
}
|
||||
@@ -270,7 +279,8 @@ template <class DataFacadeT> class MapMatchingPlugin : public BasePlugin
|
||||
const auto &input_timestamps = route_parameters.timestamps;
|
||||
if (input_timestamps.size() > 0 && input_coords.size() != input_timestamps.size())
|
||||
{
|
||||
json_result.values["status"] = "Number of timestamps does not match number of coordinates .";
|
||||
json_result.values["status"] =
|
||||
"Number of timestamps does not match number of coordinates .";
|
||||
return 400;
|
||||
}
|
||||
|
||||
@@ -289,8 +299,8 @@ template <class DataFacadeT> class MapMatchingPlugin : public BasePlugin
|
||||
return 400;
|
||||
}
|
||||
|
||||
const bool found_candidates =
|
||||
getCandiates(input_coords, route_parameters.gps_precision, sub_trace_lengths, candidates_lists);
|
||||
const bool found_candidates = getCandiates(input_coords, route_parameters.gps_precision,
|
||||
sub_trace_lengths, candidates_lists);
|
||||
if (!found_candidates)
|
||||
{
|
||||
json_result.values["status"] = "No suitable matching candidates found.";
|
||||
|
||||
Reference in New Issue
Block a user