diff --git a/include/engine/routing_algorithms/routing_base_ch.hpp b/include/engine/routing_algorithms/routing_base_ch.hpp index dd1d31eed..a5e9a3503 100644 --- a/include/engine/routing_algorithms/routing_base_ch.hpp +++ b/include/engine/routing_algorithms/routing_base_ch.hpp @@ -323,11 +323,16 @@ EdgeDuration calculateEBGNodeAnnotations(const DataFacade &facade, std::get<2>(edge) = true; // mark that this edge will now be processed - if (unpacking_cache.IsEdgeInCache(std::make_tuple( - std::get<0>(edge), std::get<1>(edge), facade.GetExcludeIndex()))) + if (unpacking_cache.IsEdgeInCache(std::make_tuple(std::get<0>(edge), + std::get<1>(edge), + facade.GetExcludeIndex(), + facade.GetTimestamp()))) { - EdgeDuration duration = unpacking_cache.GetDuration(std::make_tuple( - std::get<0>(edge), std::get<1>(edge), facade.GetExcludeIndex())); + EdgeDuration duration = + unpacking_cache.GetDuration(std::make_tuple(std::get<0>(edge), + std::get<1>(edge), + facade.GetExcludeIndex(), + facade.GetTimestamp())); duration_stack.emplace(duration); } else @@ -369,8 +374,10 @@ EdgeDuration calculateEBGNodeAnnotations(const DataFacade &facade, } else { - auto temp = std::make_tuple( - std::get<0>(edge), std::get<1>(edge), facade.GetExcludeIndex()); + auto temp = std::make_tuple(std::get<0>(edge), + std::get<1>(edge), + facade.GetExcludeIndex(), + facade.GetTimestamp()); // compute the duration here and put it onto the duration stack using method // similar to annotatePath but smaller EdgeDuration duration = @@ -391,9 +398,11 @@ EdgeDuration calculateEBGNodeAnnotations(const DataFacade &facade, duration_stack.pop(); EdgeDuration duration = edge1 + edge2; duration_stack.emplace(duration); - unpacking_cache.AddEdge( - std::make_tuple(std::get<0>(edge), std::get<1>(edge), facade.GetExcludeIndex()), - duration); + unpacking_cache.AddEdge(std::make_tuple(std::get<0>(edge), + std::get<1>(edge), + facade.GetExcludeIndex(), + facade.GetTimestamp()), + duration); } } diff --git a/include/engine/search_engine_data.hpp b/include/engine/search_engine_data.hpp index e9ab35bba..67a7c62f5 100644 --- a/include/engine/search_engine_data.hpp +++ b/include/engine/search_engine_data.hpp @@ -6,7 +6,8 @@ #include "util/query_heap.hpp" #include "util/typedefs.hpp" -#include +// #include +#include namespace osrm { @@ -47,7 +48,6 @@ template <> struct SearchEngineData using SearchEngineHeapPtr = boost::thread_specific_ptr; using ManyToManyHeapPtr = boost::thread_specific_ptr; - using UnpackingCachePtr = boost::thread_specific_ptr; static SearchEngineHeapPtr forward_heap_1; static SearchEngineHeapPtr reverse_heap_1; @@ -56,7 +56,8 @@ template <> struct SearchEngineData static SearchEngineHeapPtr forward_heap_3; static SearchEngineHeapPtr reverse_heap_3; static ManyToManyHeapPtr many_to_many_heap; - static UnpackingCachePtr unpacking_cache; + + static UnpackingCache unpacking_cache; void InitializeOrClearFirstThreadLocalStorage(unsigned number_of_nodes); @@ -65,8 +66,6 @@ template <> struct SearchEngineData void InitializeOrClearThirdThreadLocalStorage(unsigned number_of_nodes); void InitializeOrClearManyToManyThreadLocalStorage(unsigned number_of_nodes); - - void InitializeOrClearUnpackingCacheThreadLocalStorage(unsigned timestamp); }; struct MultiLayerDijkstraHeapData diff --git a/include/engine/unpacking_cache.hpp b/include/engine/unpacking_cache.hpp index eb9de8ca9..cba64fcac 100644 --- a/include/engine/unpacking_cache.hpp +++ b/include/engine/unpacking_cache.hpp @@ -2,10 +2,7 @@ #define UNPACKING_CACHE_HPP #include -<<<<<<< HEAD #include -======= ->>>>>>> 68659b398... set up for computing durations while unpacking them #include "../../third_party/compute_detail/lru_cache.hpp" #include "util/typedefs.hpp" @@ -20,13 +17,13 @@ namespace engine { typedef unsigned char ExcludeIndex; typedef unsigned Timestamp; -typedef std::tuple Key; +typedef std::tuple Key; class UnpackingCache { private: - boost::compute::detail::lru_cache, EdgeDuration> m_cache; - unsigned m_current_data_timestamp = 0; + boost::compute::detail::lru_cache m_cache; + boost::shared_mutex m_shared_access; public: // TO FIGURE OUT HOW MANY LINES TO INITIALIZE CACHE TO: @@ -34,62 +31,69 @@ class UnpackingCache // https://github.com/Project-OSRM/osrm-backend/issues/4798#issue-288608332) // LRU CACHE IMPLEMENTATION HAS THESE TWO STORAGE CONTAINERS - // Key is of size: std::uint32_t * 2 + (unsigned char) * 1 + unsigned * 1 - // = 4 * 2 + 1 * 1 + 4 * 1 = 21 + // Key is of size: std::uint32_t * 2 + (unsigned char) * 1 + // = 4 * 2 + 1 * 1 = 9 // map: n * Key + n * EdgeDuration - // = n * 21 bytes + n * std::int32_t - // = n * 21 bytes + n * 4 bytes - // = n * 25 bytes + // = n * 9 bytes + n * std::int32_t + // = n * 9 bytes + n * 4 bytes + // = n * 13 bytes // list: n * Key - // = n * 21 bytes - // Total = n * (25 + 21) = n * 46 bytes + // = n * 9 bytes + // Total = n * (13 + 9) = n * 22 bytes // Total cache size: 500 mb = 500 * 1024 *1024 bytes = 524288000 bytes // Total cache size: 1024 mb = 1024 * 1024 *1024 bytes = 1073741824 bytes // Total cache size: 500 mb = 500 * 1024 *1024 bytes = 524288000 bytes // THREAD LOCAL STORAGE (500 mb) - // Number of lines we need = 524288000 / 46 / number of threads = 11397565 / number of threads - // 16 threads: 11397565 / 16 = 712347 - // 8 threads: 11397565 / 8 = 1424695 - // 4 threads: 11397565 / 4 = 2849391 - // 2 threads: 11397565 / 2 = 5698782 + // Number of lines we need = 524288000 / 22 / number of threads = 23831272 / number of threads + // 16 threads: 23831272 / 16 = 1489454 + // 8 threads: 23831272 / 8 = 2978909 + // 4 threads: 23831272 / 4 = 5957818 + // 2 threads: 23831272 / 2 = 11915636 // THREAD LOCAL STORAGE (1024 mb) - // Number of lines we need = 1073741824 / 46 / number of threads = 23342213 / number of threads - // 16 threads: 23342213 / 16 = 1458888 - // 8 threads: 23342213 / 8 = 2917776 - // 4 threads: 23342213 / 4 = 5835553 - // 2 threads: 23342213 / 2 = 11671106 + // Number of lines we need = 1073741824 / 22 / number of threads = 48806446 / number of threads + // 16 threads: 48806446 / 16 = 3050402 + // 8 threads: 48806446 / 8 = 6100805 + // 4 threads: 48806446 / 4 = 12201611 + // 2 threads: 48806446 / 2 = 24403223 + + // LRU CACHE IMPLEMENTATION HAS THESE TWO STORAGE CONTAINERS + // Key is of size: std::uint32_t * 2 + (unsigned char) * 1 + unsigned * 1 + // = 4 * 2 + 1 * 1 + 4 * 1 = 13 + // map: n * Key + n * EdgeDuration + // = n * 13 bytes + n * std::int32_t + // = n * 13 bytes + n * 4 bytes + // = n * 17 bytes + // list: n * Key + // = n * 13 bytes + // Total = n * (17 + 13) = n * 30 bytes + // Total cache size: 500 mb = 500 * 1024 *1024 bytes = 524288000 bytes + // Total cache size: 1024 mb = 1024 * 1024 *1024 bytes = 1073741824 bytes + // Total cache size: 500 mb = 500 * 1024 *1024 bytes = 524288000 bytes // SHARED STORAGE CACHE - // Number of lines we need for shared storage cache = 524288000 / 20 = 26214400 + // Number of lines for shared storage cache 1024 mb = 524288000 / 30 = 17476266 + // Number of lines for shared storage cache 500 mb = 1073741824 / 30 = 35791394 + // Number of lines for shared storage cache 250 mb = 11397565 / 30 = 379918 - UnpackingCache(unsigned timestamp) : m_cache(11671106), m_current_data_timestamp(timestamp){}; + UnpackingCache() : m_cache(17476266){}; - UnpackingCache(std::size_t cache_size, unsigned timestamp) - : m_cache(cache_size), m_current_data_timestamp(timestamp){}; - - void Clear(unsigned new_data_timestamp) - { - if (m_current_data_timestamp != new_data_timestamp) - { - m_cache.clear(); - m_current_data_timestamp = new_data_timestamp; - } - } - - bool IsEdgeInCache(std::tuple edge) + bool IsEdgeInCache(Key edge) { + boost::shared_lock lock(m_shared_access); return m_cache.contains(edge); } - void AddEdge(std::tuple edge, EdgeDuration duration) + void AddEdge(Key edge, EdgeDuration duration) { + boost::unique_lock lock(m_shared_access); m_cache.insert(edge, duration); } - EdgeDuration GetDuration(std::tuple edge) + EdgeDuration GetDuration(Key edge) { + boost::shared_lock lock(m_shared_access); boost::optional duration = m_cache.get(edge); return duration ? *duration : MAXIMAL_EDGE_DURATION; } @@ -97,4 +101,4 @@ class UnpackingCache } // engine } // osrm -#endif // UNPACKING_CACHE_HPP +#endif // UNPACKING_CACHE_HPP \ No newline at end of file diff --git a/src/engine/routing_algorithms/many_to_many_ch.cpp b/src/engine/routing_algorithms/many_to_many_ch.cpp index 7acf47aa2..9cdcf6656 100644 --- a/src/engine/routing_algorithms/many_to_many_ch.cpp +++ b/src/engine/routing_algorithms/many_to_many_ch.cpp @@ -225,9 +225,6 @@ std::vector manyToManySearch(SearchEngineData &engi std::vector search_space_with_buckets; std::vector packed_leg; - engine_working_data.InitializeOrClearUnpackingCacheThreadLocalStorage( - facade.GetTimestamp()); // always pass in the timestamp and clear if it's different - // Populate buckets with paths from all accessible nodes to destinations via backward searches for (std::uint32_t column_idx = 0; column_idx < target_indices.size(); ++column_idx) { @@ -321,7 +318,7 @@ std::vector manyToManySearch(SearchEngineData &engi ch::calculateEBGNodeAnnotations(facade, packed_leg.begin(), packed_leg.end(), - *engine_working_data.unpacking_cache.get()); + engine_working_data.unpacking_cache); // check the direction of travel to figure out how to calculate the offset to/from // the source/target diff --git a/src/engine/search_engine_data.cpp b/src/engine/search_engine_data.cpp index 70231b6ee..59c92c5fe 100644 --- a/src/engine/search_engine_data.cpp +++ b/src/engine/search_engine_data.cpp @@ -14,7 +14,7 @@ SearchEngineData::SearchEngineHeapPtr SearchEngineData::reverse_heap_2; SearchEngineData::SearchEngineHeapPtr SearchEngineData::forward_heap_3; SearchEngineData::SearchEngineHeapPtr SearchEngineData::reverse_heap_3; SearchEngineData::ManyToManyHeapPtr SearchEngineData::many_to_many_heap; -SearchEngineData::UnpackingCachePtr SearchEngineData::unpacking_cache; +UnpackingCache SearchEngineData::unpacking_cache; void SearchEngineData::InitializeOrClearFirstThreadLocalStorage(unsigned number_of_nodes) { @@ -91,18 +91,6 @@ void SearchEngineData::InitializeOrClearManyToManyThreadLocalStorage(unsigne } } -void SearchEngineData::InitializeOrClearUnpackingCacheThreadLocalStorage(unsigned timestamp) -{ - if (unpacking_cache.get()) - { - unpacking_cache->Clear(timestamp); - } - else - { - unpacking_cache.reset(new UnpackingCache(timestamp)); - } -} - // MLD using MLD = routing_algorithms::mld::Algorithm; SearchEngineData::SearchEngineHeapPtr SearchEngineData::forward_heap_1; diff --git a/unit_tests/engine/unpacking_cache.cpp b/unit_tests/engine/unpacking_cache.cpp index d0a359a07..7a219e874 100644 --- a/unit_tests/engine/unpacking_cache.cpp +++ b/unit_tests/engine/unpacking_cache.cpp @@ -16,9 +16,9 @@ BOOST_AUTO_TEST_CASE(add_edge_and_check_existence) { // Arrange (Setup) unsigned timestamp = 1522782542; - UnpackingCache cache(1, timestamp); + UnpackingCache cache(1); - auto key = std::make_tuple(1, 1, 1); + auto key = std::make_tuple(1, 1, 1, timestamp); auto value = 1; // Act @@ -26,7 +26,7 @@ BOOST_AUTO_TEST_CASE(add_edge_and_check_existence) // Assert BOOST_CHECK(cache.IsEdgeInCache(key) == true); - BOOST_CHECK(cache.IsEdgeInCache(std::make_tuple(2, 2, 2)) == false); + BOOST_CHECK(cache.IsEdgeInCache(std::make_tuple(2, 2, 2, timestamp)) == false); auto result = cache.GetDuration(key); BOOST_CHECK_EQUAL(result, value); @@ -35,13 +35,12 @@ BOOST_AUTO_TEST_CASE(add_edge_and_check_existence) BOOST_AUTO_TEST_CASE(cache_invalidation) { // Arrange (Setup) - unsigned timestamp = 1522782542; - UnpackingCache cache(1, timestamp); + UnpackingCache cache(1); - auto key1 = std::make_tuple(1, 1, 1); + auto key1 = std::make_tuple(1, 1, 1, 1522782542); auto value1 = 1; - auto key2 = std::make_tuple(2, 2, 2); + auto key2 = std::make_tuple(2, 2, 2, 1522782543); auto value2 = 2; // Act @@ -56,31 +55,34 @@ BOOST_AUTO_TEST_CASE(cache_invalidation) BOOST_CHECK_EQUAL(result, value2); } -BOOST_AUTO_TEST_CASE(new_data) +BOOST_AUTO_TEST_CASE(store_generations) { // Arrange (Setup) + UnpackingCache cache(2); + unsigned timestamp1 = 1522782542; unsigned timestamp2 = 1522782543; - UnpackingCache cache(1, timestamp1); - - auto key1 = std::make_tuple(1, 2, 3); + auto key1 = std::make_tuple(1, 1, 1, timestamp1); auto value1 = 1; - auto key2 = std::make_tuple(2, 3, 4); + + auto key2 = std::make_tuple(1, 1, 1, timestamp2); auto value2 = 2; // Act cache.AddEdge(key1, value1); - cache.Clear(timestamp2); cache.AddEdge(key2, value2); // Assert - BOOST_CHECK(cache.IsEdgeInCache(key1) == false); + BOOST_CHECK(cache.IsEdgeInCache(key1) == true); BOOST_CHECK(cache.IsEdgeInCache(key2) == true); - BOOST_CHECK(cache.IsEdgeInCache(std::make_tuple(2, 2, 2)) == false); + BOOST_CHECK(cache.IsEdgeInCache(std::make_tuple(2, 2, 2, timestamp1)) == false); - auto result = cache.GetDuration(key2); - BOOST_CHECK_EQUAL(result, value2); + auto result1 = cache.GetDuration(key1); + BOOST_CHECK_EQUAL(result1, value1); + + auto result2 = cache.GetDuration(key2); + BOOST_CHECK_EQUAL(result2, value2); } BOOST_AUTO_TEST_SUITE_END()