Skip to content
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

Collect stats on MLD and CH performance in computing table plugin annotations with a cache by implementing a dummy cache #4820

Closed
wants to merge 10 commits into from
1 change: 1 addition & 0 deletions features/support/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ module.exports = function () {
// setup output logging
let logDir = path.join(this.LOGS_PATH, this.featureID);
this.scenarioLogFile = path.join(logDir, this.scenarioID) + '.log';
console.log(this.scenarioLogFile);
d3.queue(1)
.defer(mkdirp, logDir)
.defer(rimraf, this.scenarioLogFile)
Expand Down
44 changes: 35 additions & 9 deletions include/engine/routing_algorithms/routing_base_ch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "engine/datafacade.hpp"
#include "engine/routing_algorithms/routing_base.hpp"
#include "engine/search_engine_data.hpp"
#include "engine/unpacking_statistics.hpp"

#include "util/typedefs.hpp"

Expand Down Expand Up @@ -230,37 +231,60 @@ void unpackPath(const DataFacade<Algorithm> &facade,
BidirectionalIterator packed_path_begin,
BidirectionalIterator packed_path_end,
Callback &&callback)
{
UnpackingStatistics unpacking_cache;
unpackPath(facade, packed_path_begin, packed_path_end, unpacking_cache, callback);
}
template <typename BidirectionalIterator, typename Callback>
void unpackPath(const DataFacade<Algorithm> &facade,
BidirectionalIterator packed_path_begin,
BidirectionalIterator packed_path_end,
UnpackingStatistics &unpacking_cache,
Callback &&callback)
{
// make sure we have at least something to unpack
if (packed_path_begin == packed_path_end)
return;

std::stack<std::pair<NodeID, NodeID>> recursion_stack;
std::stack<std::tuple<NodeID, NodeID, bool>> recursion_stack;

// We have to push the path in reverse order onto the stack because it's LIFO.
for (auto current = std::prev(packed_path_end); current != packed_path_begin;
current = std::prev(current))
{
recursion_stack.emplace(*std::prev(current), *current);
recursion_stack.emplace(*std::prev(current), *current, false);
}

std::pair<NodeID, NodeID> edge;
std::tuple<NodeID, NodeID, bool> edge;
while (!recursion_stack.empty())
{
edge = recursion_stack.top();
recursion_stack.pop();

if (!std::get<2>(edge))
{

if (unpacking_cache.IsEdgeInCache(std::make_pair(std::get<0>(edge), std::get<1>(edge))))
{
std::get<2>(edge) = true;
}

unpacking_cache.CollectStats(std::make_pair(std::get<0>(edge), std::get<1>(edge)));
}

// Look for an edge on the forward CH graph (.forward)
EdgeID smaller_edge_id = facade.FindSmallestEdge(
edge.first, edge.second, [](const auto &data) { return data.forward; });
std::get<0>(edge), std::get<1>(edge), [](const auto &data) { return data.forward; });

// If we didn't find one there, the we might be looking at a part of the path that
// was found using the backward search. Here, we flip the node order (.second, .first)
// and only consider edges with the `.backward` flag.
if (SPECIAL_EDGEID == smaller_edge_id)
{
smaller_edge_id = facade.FindSmallestEdge(
edge.second, edge.first, [](const auto &data) { return data.backward; });
smaller_edge_id =
facade.FindSmallestEdge(std::get<1>(edge), std::get<0>(edge), [](const auto &data) {
return data.backward;
});
}

// If we didn't find anything *still*, then something is broken and someone has
Expand All @@ -277,13 +301,14 @@ void unpackPath(const DataFacade<Algorithm> &facade,
const NodeID middle_node_id = data.turn_id;
// Note the order here - we're adding these to a stack, so we
// want the first->middle to get visited before middle->second
recursion_stack.emplace(middle_node_id, edge.second);
recursion_stack.emplace(edge.first, middle_node_id);
recursion_stack.emplace(middle_node_id, std::get<1>(edge), std::get<2>(edge));
recursion_stack.emplace(std::get<0>(edge), middle_node_id, std::get<2>(edge));
}
else
{
auto temp = std::make_pair(std::get<0>(edge), std::get<1>(edge));
// We found an original edge, call our callback.
std::forward<Callback>(callback)(edge, smaller_edge_id);
std::forward<Callback>(callback)(temp, smaller_edge_id);
}
}
}
Expand All @@ -295,6 +320,7 @@ void unpackPath(const FacadeT &facade,
const PhantomNodes &phantom_nodes,
std::vector<PathData> &unpacked_path)
{
std::cout << "RandomIter" << std::endl;
const auto nodes_number = std::distance(packed_path_begin, packed_path_end);
BOOST_ASSERT(nodes_number > 0);

Expand Down
19 changes: 19 additions & 0 deletions include/engine/routing_algorithms/routing_base_mld.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "engine/datafacade.hpp"
#include "engine/routing_algorithms/routing_base.hpp"
#include "engine/search_engine_data.hpp"
#include "engine/unpacking_statistics.hpp"

#include "util/typedefs.hpp"

Expand Down Expand Up @@ -286,6 +287,7 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
const bool force_loop_forward,
const bool force_loop_reverse,
bool already_in_cache,
EdgeWeight weight_upper_bound,
Args... args)
{
Expand Down Expand Up @@ -361,6 +363,20 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
NodeID source, target;
bool overlay_edge;
std::tie(source, target, overlay_edge) = packed_edge;

bool child_is_in_cache = false;

if (!already_in_cache)
{
if (engine_working_data.unpacking_cache.get()->IsEdgeInCache(std::make_pair(source, target)))
{
child_is_in_cache = true;
}
// if(!already_in_cache)std::cout << facade.GetCoordinateOfNode(source) << ", "<< facade.GetCoordinateOfNode(target);
engine_working_data.unpacking_cache.get()->CollectStats(std::make_pair(source, target));
}


if (!overlay_edge)
{ // a base graph edge
unpacked_nodes.push_back(target);
Expand Down Expand Up @@ -391,6 +407,7 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
reverse_heap,
force_loop_forward,
force_loop_reverse,
child_is_in_cache,
INVALID_EDGE_WEIGHT,
sublevel,
parent_cell_id);
Expand Down Expand Up @@ -427,6 +444,7 @@ inline void search(SearchEngineData<Algorithm> &engine_working_data,
reverse_heap,
force_loop_forward,
force_loop_reverse,
false,
weight_upper_bound,
phantom_nodes);
}
Expand Down Expand Up @@ -486,6 +504,7 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
reverse_heap,
DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS,
false,
weight_upper_bound,
phantom_nodes);

Expand Down
9 changes: 9 additions & 0 deletions include/engine/search_engine_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define SEARCH_ENGINE_DATA_HPP

#include "engine/algorithm.hpp"
#include "engine/unpacking_statistics.hpp"
#include "util/query_heap.hpp"
#include "util/typedefs.hpp"

Expand Down Expand Up @@ -46,6 +47,7 @@ template <> struct SearchEngineData<routing_algorithms::ch::Algorithm>

using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>;
using ManyToManyHeapPtr = boost::thread_specific_ptr<ManyToManyQueryHeap>;
using UnpackingStatisticsPtr = boost::thread_specific_ptr<UnpackingStatistics>;

static SearchEngineHeapPtr forward_heap_1;
static SearchEngineHeapPtr reverse_heap_1;
Expand All @@ -54,6 +56,7 @@ template <> struct SearchEngineData<routing_algorithms::ch::Algorithm>
static SearchEngineHeapPtr forward_heap_3;
static SearchEngineHeapPtr reverse_heap_3;
static ManyToManyHeapPtr many_to_many_heap;
static UnpackingStatisticsPtr unpacking_cache;

void InitializeOrClearFirstThreadLocalStorage(unsigned number_of_nodes);

Expand All @@ -62,6 +65,8 @@ template <> struct SearchEngineData<routing_algorithms::ch::Algorithm>
void InitializeOrClearThirdThreadLocalStorage(unsigned number_of_nodes);

void InitializeOrClearManyToManyThreadLocalStorage(unsigned number_of_nodes);

void InitializeOrClearUnpackingStatisticsThreadLocalStorage();
};

struct MultiLayerDijkstraHeapData
Expand Down Expand Up @@ -101,14 +106,18 @@ template <> struct SearchEngineData<routing_algorithms::mld::Algorithm>

using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>;
using ManyToManyHeapPtr = boost::thread_specific_ptr<ManyToManyQueryHeap>;
using UnpackingStatisticsPtr = boost::thread_specific_ptr<UnpackingStatistics>;

static SearchEngineHeapPtr forward_heap_1;
static SearchEngineHeapPtr reverse_heap_1;
static ManyToManyHeapPtr many_to_many_heap;
static UnpackingStatisticsPtr unpacking_cache;

void InitializeOrClearFirstThreadLocalStorage(unsigned number_of_nodes);

void InitializeOrClearManyToManyThreadLocalStorage(unsigned number_of_nodes);

void InitializeOrClearUnpackingStatisticsThreadLocalStorage();
};
}
}
Expand Down
94 changes: 94 additions & 0 deletions include/engine/unpacking_statistics.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#ifndef UNPACKING_STATISTICS_HPP
#define UNPACKING_STATISTICS_HPP

#include "util/typedefs.hpp"

#include <unordered_map>
#include <utility>

namespace std
{
template <> struct hash<std::pair<NodeID, NodeID>>
{
typedef std::pair<NodeID, NodeID> argument_type;
typedef std::size_t result_type;
result_type operator()(argument_type const &pair) const noexcept
{
result_type const h1(std::hash<unsigned int>{}(pair.first));
result_type const h2(std::hash<unsigned int>{}(pair.second));
return h1 ^ (h2 << 1); // or use boost::hash_combine (see Discussion)
}
};
}
namespace osrm
{
namespace engine
{
class UnpackingStatistics
{
std::pair<NodeID, NodeID> edge;
std::unordered_map<std::pair<NodeID, NodeID>, int> cache;
int number_of_lookups;
int number_of_finds;
int number_of_misses;

public:
UnpackingStatistics() : number_of_lookups(0), number_of_finds(0), number_of_misses(0) {}

void Clear()
{
cache.clear();
number_of_lookups = 0;
number_of_finds = 0;
number_of_misses = 0;
}

bool IsEdgeInCache(std::pair<NodeID, NodeID> edge)
{
++number_of_lookups;
bool edge_is_in_cache = cache.find(edge) != cache.end();
// if (edge_is_in_cache) {
// std::cout << edge.first << ", " << edge.second << " true" << std::endl;
// } else {
// std::cout << edge.first << ", " << edge.second << " false" << std::endl;
// }
return edge_is_in_cache;
}

void CollectStats(std::pair<NodeID, NodeID> edge)
{

// check if edge is in the map
// if edge is in the map :
// - increment number_of_lookups, number_of_finds
// - update cache with edge:number_of_times to edge:number_of_times++
// if edge is not in map:
// - increment number_of_lookups, number_of_misses
// - insert edge into map with value 1

if (cache.find(edge) == cache.end())
{
++number_of_misses;
}
else
{
++number_of_finds;
}
++cache[edge];
}

void PrintStats()
{
// std::cout << "Total Misses :" << number_of_misses << " Total Finds: " << number_of_finds
// << " Total Lookups: " << number_of_lookups << " Cache size: " << cache.size() << std::endl;
std::cout << number_of_misses << "," << number_of_finds << "," << number_of_lookups << "," << cache.size() << std::endl;
}

// void PrintEdgeLookups(std::pair<NodeID, NodeID> edge)
// {
// }
};
} // engine
} // osrm

#endif // UNPACKING_STATISTICS_HPP
1 change: 1 addition & 0 deletions src/engine/routing_algorithms/alternative_path_mld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,7 @@ void unpackPackedPaths(InputIt first,
reverse_heap,
DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS,
false,
INVALID_EDGE_WEIGHT,
sublevel,
parent_cell_id);
Expand Down
17 changes: 15 additions & 2 deletions src/engine/routing_algorithms/direct_shortest_path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,26 @@ InternalRouteResult directShortestPathSearch(SearchEngineData<ch::Algorithm> &en
ch::unpackPath(facade,
packed_leg.begin(),
packed_leg.end(),
*engine_working_data.unpacking_cache.get(),
[&unpacked_nodes, &unpacked_edges](std::pair<NodeID, NodeID> &edge,
const auto &edge_id) {
BOOST_ASSERT(edge.first == unpacked_nodes.back());
unpacked_nodes.push_back(edge.second);
unpacked_edges.push_back(edge_id);
unpacked_nodes.push_back(edge.second); // edge.second is edge based node ids
unpacked_edges.push_back(edge_id);
});
engine_working_data.unpacking_cache.get()->PrintStats();
}

return extractRoute(facade, weight, phantom_nodes, unpacked_nodes, unpacked_edges);
// a function that takes the endge based node ids and returns to you the duration
// takes path returns duration
// path is made of Edge based edges == turns that are unpacked edges and unpacked nodes
//
// / \ get the duration of the street segment , get the duration of the turn segment and add them up for total duration
// |
// - - -
//
// what I should really do first is read extractRoute implementation and understand what is happenin in there
}

template <>
Expand All @@ -85,8 +96,10 @@ InternalRouteResult directShortestPathSearch(SearchEngineData<mld::Algorithm> &e
reverse_heap,
DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS,
false,
INVALID_EDGE_WEIGHT,
phantom_nodes);
engine_working_data.unpacking_cache.get()->PrintStats();

return extractRoute(facade, weight, phantom_nodes, unpacked_nodes, unpacked_edges);
}
Expand Down
Loading