From 4e5bf05518e3b3c4558156731e221346cae0e775 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Tue, 11 Jun 2024 17:53:40 +0200 Subject: [PATCH 01/47] Try to use boost::fast_pool_allocator in QueryHeap --- include/util/query_heap.hpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/include/util/query_heap.hpp b/include/util/query_heap.hpp index 9ded36c9e86..5796c356375 100644 --- a/include/util/query_heap.hpp +++ b/include/util/query_heap.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -121,7 +122,16 @@ template class UnorderedMapStorage void Clear() { nodes.clear(); } private: - std::unordered_map nodes; + template + using PoolAllocator = boost::fast_pool_allocator; + + template + using UnorderedMap = std:: + unordered_map, std::equal_to, PoolAllocator>>; + + UnorderedMap nodes; }; template Date: Tue, 11 Jun 2024 22:37:59 +0200 Subject: [PATCH 02/47] wip From 3bd897ffe1a7265634dcd07f713910ad1d88e24d Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Wed, 12 Jun 2024 09:23:36 +0200 Subject: [PATCH 03/47] wip From 0723dc073c6b05e29d2d38fdfe558870862be19b Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Wed, 3 Jul 2024 21:51:05 +0300 Subject: [PATCH 04/47] wip --- include/util/query_heap.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/util/query_heap.hpp b/include/util/query_heap.hpp index 5796c356375..0639cb3860a 100644 --- a/include/util/query_heap.hpp +++ b/include/util/query_heap.hpp @@ -12,7 +12,6 @@ #include #include #include - namespace osrm::util { @@ -217,10 +216,12 @@ class QueryHeap return weight > other.weight; } }; + using HeapContainerAllocator = boost::fast_pool_allocator; using HeapContainer = boost::heap::d_ary_heap, boost::heap::mutable_, - boost::heap::compare>>; + boost::heap::compare>, + boost::heap::allocator>; using HeapHandle = typename HeapContainer::handle_type; public: From bbdac63362276a45427733850f329e1fe851baf8 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Wed, 3 Jul 2024 21:55:16 +0300 Subject: [PATCH 05/47] wip --- include/util/query_heap.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/util/query_heap.hpp b/include/util/query_heap.hpp index 0639cb3860a..dcf09b5f0d7 100644 --- a/include/util/query_heap.hpp +++ b/include/util/query_heap.hpp @@ -216,7 +216,10 @@ class QueryHeap return weight > other.weight; } }; - using HeapContainerAllocator = boost::fast_pool_allocator; + using HeapContainerAllocator = + boost::fast_pool_allocator; using HeapContainer = boost::heap::d_ary_heap, boost::heap::mutable_, From 611a3c250b1fdf9d52c857e2e2ba65394d3d8851 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Wed, 3 Jul 2024 22:27:47 +0300 Subject: [PATCH 06/47] wip --- include/engine/guidance/assemble_geometry.hpp | 5 +++++ include/util/query_heap.hpp | 10 ++-------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/include/engine/guidance/assemble_geometry.hpp b/include/engine/guidance/assemble_geometry.hpp index 4001f6089d6..386d39d8ddc 100644 --- a/include/engine/guidance/assemble_geometry.hpp +++ b/include/engine/guidance/assemble_geometry.hpp @@ -36,6 +36,11 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, const bool reversed_target) { LegGeometry geometry; + geometry.locations.reserve(leg_data.size() + 2); + geometry.segment_distances.reserve(leg_data.size() + 1); + geometry.segment_offsets.reserve(leg_data.size() + 1); + geometry.annotations.reserve(leg_data.size() + 1); + geometry.node_ids.reserve(leg_data.size() + 2); // segment 0 first and last geometry.segment_offsets.push_back(0); diff --git a/include/util/query_heap.hpp b/include/util/query_heap.hpp index dcf09b5f0d7..37b4e33e0a6 100644 --- a/include/util/query_heap.hpp +++ b/include/util/query_heap.hpp @@ -121,10 +121,7 @@ template class UnorderedMapStorage void Clear() { nodes.clear(); } private: - template - using PoolAllocator = boost::fast_pool_allocator; + template using PoolAllocator = boost::fast_pool_allocator; template using UnorderedMap = std:: @@ -216,10 +213,7 @@ class QueryHeap return weight > other.weight; } }; - using HeapContainerAllocator = - boost::fast_pool_allocator; + using HeapContainerAllocator = boost::fast_pool_allocator; using HeapContainer = boost::heap::d_ary_heap, boost::heap::mutable_, From f62e91722682e39e7cb9c770491729b332fd419e Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Sat, 6 Jul 2024 12:40:57 +0300 Subject: [PATCH 07/47] wip --- include/util/query_heap.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/util/query_heap.hpp b/include/util/query_heap.hpp index 37b4e33e0a6..3329adea332 100644 --- a/include/util/query_heap.hpp +++ b/include/util/query_heap.hpp @@ -213,7 +213,7 @@ class QueryHeap return weight > other.weight; } }; - using HeapContainerAllocator = boost::fast_pool_allocator; + using HeapContainerAllocator = std::allocator; // boost::fast_pool_allocator; using HeapContainer = boost::heap::d_ary_heap, boost::heap::mutable_, From 5f166a5e4ea60f0cac0db84df55e16a88c6832c2 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Sat, 6 Jul 2024 12:43:21 +0300 Subject: [PATCH 08/47] wip --- include/util/query_heap.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/util/query_heap.hpp b/include/util/query_heap.hpp index 3329adea332..e2d3ed4a9db 100644 --- a/include/util/query_heap.hpp +++ b/include/util/query_heap.hpp @@ -213,7 +213,8 @@ class QueryHeap return weight > other.weight; } }; - using HeapContainerAllocator = std::allocator; // boost::fast_pool_allocator; + using HeapContainerAllocator = + std::allocator; // boost::fast_pool_allocator; using HeapContainer = boost::heap::d_ary_heap, boost::heap::mutable_, From 8df282b2e614384fe97526e0535a5fc0efd4095b Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Tue, 9 Jul 2024 21:15:50 +0200 Subject: [PATCH 09/47] wip --- include/util/query_heap.hpp | 59 ++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/include/util/query_heap.hpp b/include/util/query_heap.hpp index e2d3ed4a9db..83814a470af 100644 --- a/include/util/query_heap.hpp +++ b/include/util/query_heap.hpp @@ -1,12 +1,13 @@ #ifndef OSRM_UTIL_QUERY_HEAP_HPP #define OSRM_UTIL_QUERY_HEAP_HPP +#include "util/pool_allocator.hpp" +#include #include #include - -#include #include #include +#include #include #include #include @@ -121,8 +122,6 @@ template class UnorderedMapStorage void Clear() { nodes.clear(); } private: - template using PoolAllocator = boost::fast_pool_allocator; - template using UnorderedMap = std:: unordered_map, std::equal_to, PoolAllocator>>; @@ -191,6 +190,53 @@ class TwoLevelStorage OverlayIndexStorage overlay; }; +template class LoggingAllocator +{ + public: + using value_type = T; + + LoggingAllocator() noexcept = default; + template LoggingAllocator(const LoggingAllocator &) noexcept {} + + T *allocate(std::size_t n) + { + if (n == 1024) + { + std::cerr << "bingo\n"; + } + + auto p = std::allocator().allocate(n); + if (n != 1) + { + std::cout << "Allocated " << n << " element(s) of size " << sizeof(T) << " at " + << static_cast(p) << std::endl; + } + + return p; + } + + void deallocate(T *p, std::size_t n) noexcept + { + // std::cout << "Deallocated " << n << " element(s) at " << static_cast(p) << + // std::endl; + std::allocator().deallocate(p, n); + } + + template void construct(U *p, Args &&...args) + { + std::allocator a; + // std::cout << "Constructing object at " << static_cast(p) << std::endl; + std::allocator_traits>::construct(a, p, std::forward(args)...); + } + + template void destroy(U *p) + { + // std::cout << "Destroying object at " << static_cast(p) << std::endl; + std::allocator a; + std::allocator_traits>::destroy(a, p); + } +}; + template other.weight; } }; - using HeapContainerAllocator = - std::allocator; // boost::fast_pool_allocator; using HeapContainer = boost::heap::d_ary_heap, boost::heap::mutable_, boost::heap::compare>, - boost::heap::allocator>; + boost::heap::allocator>>; using HeapHandle = typename HeapContainer::handle_type; public: @@ -244,6 +288,7 @@ class QueryHeap heap.clear(); inserted_nodes.clear(); node_index.Clear(); + heap.reserve(1024); } std::size_t Size() const { return heap.size(); } From c578698da0f815f890af5d39ca8aa245955401c3 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Tue, 9 Jul 2024 21:28:22 +0200 Subject: [PATCH 10/47] wip --- include/util/pool_allocator.hpp | 83 +++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 include/util/pool_allocator.hpp diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp new file mode 100644 index 00000000000..e010bfe3a72 --- /dev/null +++ b/include/util/pool_allocator.hpp @@ -0,0 +1,83 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace osrm::util +{ + +template class PoolAllocator +{ + public: + using value_type = T; + + T *allocate(std::size_t n) + { + size_t free_list_index = get_next_power_of_two_exponent(n); + auto &free_list = free_lists_[free_list_index]; + const auto items_in_block = 1u << free_list_index; + if (free_list.empty()) + { + // Check if there is space in current block + if (current_block_left_items_ < items_in_block) + { + allocate_block(items_in_block); + } + + free_list.push_back(current_block_ptr_); + current_block_left_items_ -= items_in_block; + current_block_ptr_ += items_in_block; + } + auto ptr = free_list.back(); + free_list.pop_back(); + return ptr; + } + + void deallocate(T *p, std::size_t n) noexcept + { + size_t free_list_index = get_next_power_of_two_exponent(n); + free_lists_[free_list_index].push_back(p); + } + + ~PoolAllocator() + { + for (auto block : blocks_) + { + std::free(block); + } + } + + private: + size_t get_next_power_of_two_exponent(size_t n) const + { + return std::countr_zero(std::bit_ceil(n)); + } + + void allocate_block(size_t items_in_block) + { + size_t block_size = std::max(items_in_block, (size_t)256) * sizeof(T); + T *block = static_cast(std::malloc(block_size)); + if (!block) + { + throw std::bad_alloc(); + } + blocks_.push_back(block); + current_block_ = block; + current_block_ptr_ = block; + current_block_left_items_ = block_size / sizeof(T); + } + + std::array, 32> free_lists_; + std::vector blocks_; + T *current_block_ = nullptr; + T *current_block_ptr_ = nullptr; + size_t current_block_left_items_ = 0; +}; + +} // namespace osrm::util From d1f04abf4292f4070950ad34deafac20c564ff02 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Tue, 9 Jul 2024 22:27:21 +0200 Subject: [PATCH 11/47] wip --- include/engine/guidance/assemble_geometry.hpp | 5 --- include/util/pool_allocator.hpp | 42 +++++++++++++++---- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/include/engine/guidance/assemble_geometry.hpp b/include/engine/guidance/assemble_geometry.hpp index 386d39d8ddc..4001f6089d6 100644 --- a/include/engine/guidance/assemble_geometry.hpp +++ b/include/engine/guidance/assemble_geometry.hpp @@ -36,11 +36,6 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, const bool reversed_target) { LegGeometry geometry; - geometry.locations.reserve(leg_data.size() + 2); - geometry.segment_distances.reserve(leg_data.size() + 1); - geometry.segment_offsets.reserve(leg_data.size() + 1); - geometry.annotations.reserve(leg_data.size() + 1); - geometry.node_ids.reserve(leg_data.size() + 2); // segment 0 first and last geometry.segment_offsets.push_back(0); diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index e010bfe3a72..23b8737dbc0 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -12,11 +12,21 @@ namespace osrm::util { -template class PoolAllocator +#if 1 +template class PoolAllocator { public: using value_type = T; + PoolAllocator() noexcept = default; + + template PoolAllocator(const PoolAllocator &) noexcept {} + + template struct rebind + { + using other = PoolAllocator; + }; + T *allocate(std::size_t n) { size_t free_list_index = get_next_power_of_two_exponent(n); @@ -56,28 +66,46 @@ template class PoolAllocator private: size_t get_next_power_of_two_exponent(size_t n) const { - return std::countr_zero(std::bit_ceil(n)); + BOOST_ASSERT(n > 0); + return (sizeof(size_t) * 8) - std::countl_zero(n - 1); } void allocate_block(size_t items_in_block) { - size_t block_size = std::max(items_in_block, (size_t)256) * sizeof(T); - T *block = static_cast(std::malloc(block_size)); + items_in_block = std::max(items_in_block, MinItemsInBlock); + size_t block_size = items_in_block * sizeof(T); + T *block = static_cast(std::aligned_alloc(alignof(T), block_size)); if (!block) { throw std::bad_alloc(); } + total_allocated_ += block_size; blocks_.push_back(block); - current_block_ = block; current_block_ptr_ = block; - current_block_left_items_ = block_size / sizeof(T); + current_block_left_items_ = items_in_block; } std::array, 32> free_lists_; std::vector blocks_; - T *current_block_ = nullptr; T *current_block_ptr_ = nullptr; size_t current_block_left_items_ = 0; + + size_t total_allocated_ = 0; }; +template +bool operator==(const PoolAllocator &, const PoolAllocator &) +{ + return true; +} + +template +bool operator!=(const PoolAllocator &, const PoolAllocator &) +{ + return false; +} + +#else +template using PoolAllocator = std::allocator; +#endif } // namespace osrm::util From 233a7563b6a9f011414e484e91a10f2721d56333 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Tue, 9 Jul 2024 22:39:43 +0200 Subject: [PATCH 12/47] wip --- .github/workflows/osrm-backend.yml | 588 ++++++++++++++--------------- 1 file changed, 294 insertions(+), 294 deletions(-) diff --git a/.github/workflows/osrm-backend.yml b/.github/workflows/osrm-backend.yml index 454e273f4ec..0af12b9e77c 100644 --- a/.github/workflows/osrm-backend.yml +++ b/.github/workflows/osrm-backend.yml @@ -23,159 +23,159 @@ concurrency: cancel-in-progress: true jobs: - windows-release-node: - needs: format-taginfo-docs - runs-on: windows-2022 - continue-on-error: false - env: - BUILD_TYPE: Release - steps: - - uses: actions/checkout@v4 - - run: pip install "conan<2.0.0" - - run: conan --version - - run: cmake --version - - uses: actions/setup-node@v4 - with: - node-version: 18 - - run: node --version - - run: npm --version - - name: Prepare environment - shell: bash - run: | - PACKAGE_JSON_VERSION=$(node -e "console.log(require('./package.json').version)") - echo PUBLISH=$([[ "${GITHUB_REF:-}" == "refs/tags/v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off") >> $GITHUB_ENV - - run: npm install --ignore-scripts - - run: npm link --ignore-scripts - - name: Build - shell: bash - run: | - mkdir build - cd build - cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_CONAN=ON -DENABLE_NODE_BINDINGS=ON .. - cmake --build . --config Release + # windows-release-node: + # needs: format-taginfo-docs + # runs-on: windows-2022 + # continue-on-error: false + # env: + # BUILD_TYPE: Release + # steps: + # - uses: actions/checkout@v4 + # - run: pip install "conan<2.0.0" + # - run: conan --version + # - run: cmake --version + # - uses: actions/setup-node@v4 + # with: + # node-version: 18 + # - run: node --version + # - run: npm --version + # - name: Prepare environment + # shell: bash + # run: | + # PACKAGE_JSON_VERSION=$(node -e "console.log(require('./package.json').version)") + # echo PUBLISH=$([[ "${GITHUB_REF:-}" == "refs/tags/v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off") >> $GITHUB_ENV + # - run: npm install --ignore-scripts + # - run: npm link --ignore-scripts + # - name: Build + # shell: bash + # run: | + # mkdir build + # cd build + # cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_CONAN=ON -DENABLE_NODE_BINDINGS=ON .. + # cmake --build . --config Release - # TODO: MSVC goes out of memory when building our tests - # - name: Run tests - # shell: bash - # run: | - # cd build - # cmake --build . --config Release --target tests - # # TODO: run tests - # - name: Run node tests - # shell: bash - # run: | - # ./lib/binding/osrm-extract.exe -p profiles/car.lua test/data/monaco.osm.pbf - - # mkdir -p test/data/ch - # cp test/data/monaco.osrm* test/data/ch/ - # ./lib/binding/osrm-contract.exe test/data/ch/monaco.osrm - - # ./lib/binding/osrm-datastore.exe test/data/ch/monaco.osrm - # node test/nodejs/index.js - - name: Build Node package - shell: bash - run: ./scripts/ci/node_package.sh - - name: Publish Node package - if: ${{ env.PUBLISH == 'On' }} - uses: ncipollo/release-action@v1 - with: - allowUpdates: true - artifactErrorsFailBuild: true - artifacts: build/stage/**/*.tar.gz - omitBody: true - omitBodyDuringUpdate: true - omitName: true - omitNameDuringUpdate: true - replacesArtifacts: true - token: ${{ secrets.GITHUB_TOKEN }} - - format-taginfo-docs: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v4 - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: 18 - - name: Enable Node.js cache - uses: actions/cache@v4 - with: - path: ~/.npm - key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-node- - - name: Prepare environment - run: | - npm ci --ignore-scripts - clang-format-15 --version - - name: Run checks - run: | - ./scripts/check_taginfo.py taginfo.json profiles/car.lua - ./scripts/format.sh && ./scripts/error_on_dirty.sh - node ./scripts/validate_changelog.js - npm run docs && ./scripts/error_on_dirty.sh - npm audit --production - - docker-image-matrix: - strategy: - matrix: - docker-base-image: ["debian", "alpine"] - needs: format-taginfo-docs - runs-on: ubuntu-22.04 - continue-on-error: false - steps: - - name: Check out the repo - uses: actions/checkout@v4 - - name: Enable osm.pbf cache - uses: actions/cache@v4 - with: - path: berlin-latest.osm.pbf - key: v1-berlin-osm-pbf - restore-keys: | - v1-berlin-osm-pbf - - name: Docker build - run: | - docker build -t osrm-backend-local -f docker/Dockerfile-${{ matrix.docker-base-image }} . - - name: Test Docker image - run: | - if [ ! -f "${PWD}/berlin-latest.osm.pbf" ]; then - wget http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf - fi - TAG=osrm-backend-local - # when `--memory-swap` value equals `--memory` it means container won't use swap - # see https://docs.docker.com/config/containers/resource_constraints/#--memory-swap-details - MEMORY_ARGS="--memory=1g --memory-swap=1g" - docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-extract --dump-nbg-graph -p /opt/car.lua /data/berlin-latest.osm.pbf - docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-components /data/berlin-latest.osrm.nbg /data/berlin-latest.geojson - if [ ! -s "${PWD}/berlin-latest.geojson" ] - then - >&2 echo "No berlin-latest.geojson found" - exit 1 - fi - # removing `.osrm.nbg` to check that whole pipeline works without it - rm -rf "${PWD}/berlin-latest.osrm.nbg" - - docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-partition /data/berlin-latest.osrm - docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-customize /data/berlin-latest.osrm - docker run $MEMORY_ARGS --name=osrm-container -t -p 5000:5000 -v "${PWD}:/data" "${TAG}" osrm-routed --algorithm mld /data/berlin-latest.osrm & - curl --retry-delay 3 --retry 10 --retry-all-errors "http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true" - docker stop osrm-container + # # TODO: MSVC goes out of memory when building our tests + # # - name: Run tests + # # shell: bash + # # run: | + # # cd build + # # cmake --build . --config Release --target tests + # # # TODO: run tests + # # - name: Run node tests + # # shell: bash + # # run: | + # # ./lib/binding/osrm-extract.exe -p profiles/car.lua test/data/monaco.osm.pbf + + # # mkdir -p test/data/ch + # # cp test/data/monaco.osrm* test/data/ch/ + # # ./lib/binding/osrm-contract.exe test/data/ch/monaco.osrm + + # # ./lib/binding/osrm-datastore.exe test/data/ch/monaco.osrm + # # node test/nodejs/index.js + # - name: Build Node package + # shell: bash + # run: ./scripts/ci/node_package.sh + # - name: Publish Node package + # if: ${{ env.PUBLISH == 'On' }} + # uses: ncipollo/release-action@v1 + # with: + # allowUpdates: true + # artifactErrorsFailBuild: true + # artifacts: build/stage/**/*.tar.gz + # omitBody: true + # omitBodyDuringUpdate: true + # omitName: true + # omitNameDuringUpdate: true + # replacesArtifacts: true + # token: ${{ secrets.GITHUB_TOKEN }} + + # format-taginfo-docs: + # runs-on: ubuntu-22.04 + # steps: + # - uses: actions/checkout@v4 + # - name: Use Node.js + # uses: actions/setup-node@v4 + # with: + # node-version: 18 + # - name: Enable Node.js cache + # uses: actions/cache@v4 + # with: + # path: ~/.npm + # key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + # restore-keys: | + # ${{ runner.os }}-node- + # - name: Prepare environment + # run: | + # npm ci --ignore-scripts + # clang-format-15 --version + # - name: Run checks + # run: | + # ./scripts/check_taginfo.py taginfo.json profiles/car.lua + # ./scripts/format.sh && ./scripts/error_on_dirty.sh + # node ./scripts/validate_changelog.js + # npm run docs && ./scripts/error_on_dirty.sh + # npm audit --production + + # docker-image-matrix: + # strategy: + # matrix: + # docker-base-image: ["debian", "alpine"] + # needs: format-taginfo-docs + # runs-on: ubuntu-22.04 + # continue-on-error: false + # steps: + # - name: Check out the repo + # uses: actions/checkout@v4 + # - name: Enable osm.pbf cache + # uses: actions/cache@v4 + # with: + # path: berlin-latest.osm.pbf + # key: v1-berlin-osm-pbf + # restore-keys: | + # v1-berlin-osm-pbf + # - name: Docker build + # run: | + # docker build -t osrm-backend-local -f docker/Dockerfile-${{ matrix.docker-base-image }} . + # - name: Test Docker image + # run: | + # if [ ! -f "${PWD}/berlin-latest.osm.pbf" ]; then + # wget http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf + # fi + # TAG=osrm-backend-local + # # when `--memory-swap` value equals `--memory` it means container won't use swap + # # see https://docs.docker.com/config/containers/resource_constraints/#--memory-swap-details + # MEMORY_ARGS="--memory=1g --memory-swap=1g" + # docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-extract --dump-nbg-graph -p /opt/car.lua /data/berlin-latest.osm.pbf + # docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-components /data/berlin-latest.osrm.nbg /data/berlin-latest.geojson + # if [ ! -s "${PWD}/berlin-latest.geojson" ] + # then + # >&2 echo "No berlin-latest.geojson found" + # exit 1 + # fi + # # removing `.osrm.nbg` to check that whole pipeline works without it + # rm -rf "${PWD}/berlin-latest.osrm.nbg" + + # docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-partition /data/berlin-latest.osrm + # docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-customize /data/berlin-latest.osrm + # docker run $MEMORY_ARGS --name=osrm-container -t -p 5000:5000 -v "${PWD}:/data" "${TAG}" osrm-routed --algorithm mld /data/berlin-latest.osrm & + # curl --retry-delay 3 --retry 10 --retry-all-errors "http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true" + # docker stop osrm-container build-test-publish: - needs: format-taginfo-docs + #needs: format-taginfo-docs strategy: matrix: include: - - name: gcc-13-debug-cov - continue-on-error: false - node: 20 - runs-on: ubuntu-24.04 - BUILD_TOOLS: ON - BUILD_TYPE: Debug - CCOMPILER: gcc-13 - CUCUMBER_TIMEOUT: 20000 - CXXCOMPILER: g++-13 - ENABLE_COVERAGE: ON + # - name: gcc-13-debug-cov + # continue-on-error: false + # node: 20 + # runs-on: ubuntu-24.04 + # BUILD_TOOLS: ON + # BUILD_TYPE: Debug + # CCOMPILER: gcc-13 + # CUCUMBER_TIMEOUT: 20000 + # CXXCOMPILER: g++-13 + # ENABLE_COVERAGE: ON - name: clang-18-debug-asan-ubsan continue-on-error: false @@ -191,61 +191,61 @@ jobs: OSRM_CONNECTION_RETRIES: 10 OSRM_CONNECTION_EXP_BACKOFF_COEF: 1.5 - - name: clang-18-release - continue-on-error: false - node: 18 - runs-on: ubuntu-24.04 - BUILD_TOOLS: ON - BUILD_TYPE: Release - CCOMPILER: clang-18 - CXXCOMPILER: clang++-18 - CUCUMBER_TIMEOUT: 60000 - ENABLE_LTO: OFF - - - name: clang-18-debug - continue-on-error: false - node: 18 - runs-on: ubuntu-24.04 - BUILD_TOOLS: ON - BUILD_TYPE: Debug - CCOMPILER: clang-18 - CXXCOMPILER: clang++-18 - CUCUMBER_TIMEOUT: 60000 - ENABLE_LTO: OFF - - - name: clang-18-debug-clang-tidy - continue-on-error: false - node: 18 - runs-on: ubuntu-24.04 - BUILD_TOOLS: ON - BUILD_TYPE: Debug - CCOMPILER: clang-18 - CXXCOMPILER: clang++-18 - CUCUMBER_TIMEOUT: 60000 - ENABLE_CLANG_TIDY: ON - - - - name: clang-17-release - continue-on-error: false - node: 18 - runs-on: ubuntu-24.04 - BUILD_TOOLS: ON - BUILD_TYPE: Release - CCOMPILER: clang-17 - CXXCOMPILER: clang++-17 - CUCUMBER_TIMEOUT: 60000 - ENABLE_LTO: OFF - - - name: clang-16-release - continue-on-error: false - node: 18 - runs-on: ubuntu-24.04 - BUILD_TOOLS: ON - BUILD_TYPE: Release - CCOMPILER: clang-16 - CXXCOMPILER: clang++-16 - CUCUMBER_TIMEOUT: 60000 - ENABLE_LTO: OFF + # - name: clang-18-release + # continue-on-error: false + # node: 18 + # runs-on: ubuntu-24.04 + # BUILD_TOOLS: ON + # BUILD_TYPE: Release + # CCOMPILER: clang-18 + # CXXCOMPILER: clang++-18 + # CUCUMBER_TIMEOUT: 60000 + # ENABLE_LTO: OFF + + # - name: clang-18-debug + # continue-on-error: false + # node: 18 + # runs-on: ubuntu-24.04 + # BUILD_TOOLS: ON + # BUILD_TYPE: Debug + # CCOMPILER: clang-18 + # CXXCOMPILER: clang++-18 + # CUCUMBER_TIMEOUT: 60000 + # ENABLE_LTO: OFF + + # - name: clang-18-debug-clang-tidy + # continue-on-error: false + # node: 18 + # runs-on: ubuntu-24.04 + # BUILD_TOOLS: ON + # BUILD_TYPE: Debug + # CCOMPILER: clang-18 + # CXXCOMPILER: clang++-18 + # CUCUMBER_TIMEOUT: 60000 + # ENABLE_CLANG_TIDY: ON + + + # - name: clang-17-release + # continue-on-error: false + # node: 18 + # runs-on: ubuntu-24.04 + # BUILD_TOOLS: ON + # BUILD_TYPE: Release + # CCOMPILER: clang-17 + # CXXCOMPILER: clang++-17 + # CUCUMBER_TIMEOUT: 60000 + # ENABLE_LTO: OFF + + # - name: clang-16-release + # continue-on-error: false + # node: 18 + # runs-on: ubuntu-24.04 + # BUILD_TOOLS: ON + # BUILD_TYPE: Release + # CCOMPILER: clang-16 + # CXXCOMPILER: clang++-16 + # CUCUMBER_TIMEOUT: 60000 + # ENABLE_LTO: OFF - name: conan-linux-debug-asan-ubsan continue-on-error: false @@ -259,92 +259,92 @@ jobs: ENABLE_SANITIZER: ON ENABLE_LTO: OFF - - name: conan-linux-release - continue-on-error: false - node: 18 - runs-on: ubuntu-24.04 - BUILD_TOOLS: ON - BUILD_TYPE: Release - CCOMPILER: clang-18 - CXXCOMPILER: clang++-18 - ENABLE_CONAN: ON - ENABLE_LTO: OFF - - - name: gcc-14-release - continue-on-error: false - node: 20 - runs-on: ubuntu-24.04 - BUILD_TOOLS: ON - BUILD_TYPE: Release - CCOMPILER: gcc-14 - CXXCOMPILER: g++-14 - CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized' - - - name: gcc-13-release - continue-on-error: false - node: 20 - runs-on: ubuntu-24.04 - BUILD_TOOLS: ON - BUILD_TYPE: Release - CCOMPILER: gcc-13 - CXXCOMPILER: g++-13 - CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized' - - - name: gcc-12-release - continue-on-error: false - node: 20 - runs-on: ubuntu-22.04 - BUILD_TOOLS: ON - BUILD_TYPE: Release - CCOMPILER: gcc-12 - CXXCOMPILER: g++-12 - CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized' - - - name: conan-linux-release-node - build_node_package: true - continue-on-error: false - node: 20 - runs-on: ubuntu-24.04 - BUILD_TYPE: Release - CCOMPILER: clang-16 - CXXCOMPILER: clang++-16 - ENABLE_CONAN: ON - NODE_PACKAGE_TESTS_ONLY: ON - - - name: conan-linux-debug-node - build_node_package: true - continue-on-error: false - node: 20 - runs-on: ubuntu-24.04 - BUILD_TYPE: Debug - CCOMPILER: clang-16 - CXXCOMPILER: clang++-16 - ENABLE_CONAN: ON - NODE_PACKAGE_TESTS_ONLY: ON - - - name: conan-macos-x64-release-node - build_node_package: true - continue-on-error: true - node: 20 - runs-on: macos-13 # x86_64 - BUILD_TYPE: Release - CCOMPILER: clang - CXXCOMPILER: clang++ - CUCUMBER_TIMEOUT: 60000 - ENABLE_ASSERTIONS: ON - ENABLE_CONAN: ON - - - name: conan-macos-arm64-release-node - build_node_package: true - continue-on-error: true - node: 20 - runs-on: macos-14 # arm64 - BUILD_TYPE: Release - CCOMPILER: clang - CXXCOMPILER: clang++ - CUCUMBER_TIMEOUT: 60000 - ENABLE_ASSERTIONS: ON - ENABLE_CONAN: ON + # - name: conan-linux-release + # continue-on-error: false + # node: 18 + # runs-on: ubuntu-24.04 + # BUILD_TOOLS: ON + # BUILD_TYPE: Release + # CCOMPILER: clang-18 + # CXXCOMPILER: clang++-18 + # ENABLE_CONAN: ON + # ENABLE_LTO: OFF + + # - name: gcc-14-release + # continue-on-error: false + # node: 20 + # runs-on: ubuntu-24.04 + # BUILD_TOOLS: ON + # BUILD_TYPE: Release + # CCOMPILER: gcc-14 + # CXXCOMPILER: g++-14 + # CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized' + + # - name: gcc-13-release + # continue-on-error: false + # node: 20 + # runs-on: ubuntu-24.04 + # BUILD_TOOLS: ON + # BUILD_TYPE: Release + # CCOMPILER: gcc-13 + # CXXCOMPILER: g++-13 + # CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized' + + # - name: gcc-12-release + # continue-on-error: false + # node: 20 + # runs-on: ubuntu-22.04 + # BUILD_TOOLS: ON + # BUILD_TYPE: Release + # CCOMPILER: gcc-12 + # CXXCOMPILER: g++-12 + # CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized' + + # - name: conan-linux-release-node + # build_node_package: true + # continue-on-error: false + # node: 20 + # runs-on: ubuntu-24.04 + # BUILD_TYPE: Release + # CCOMPILER: clang-16 + # CXXCOMPILER: clang++-16 + # ENABLE_CONAN: ON + # NODE_PACKAGE_TESTS_ONLY: ON + + # - name: conan-linux-debug-node + # build_node_package: true + # continue-on-error: false + # node: 20 + # runs-on: ubuntu-24.04 + # BUILD_TYPE: Debug + # CCOMPILER: clang-16 + # CXXCOMPILER: clang++-16 + # ENABLE_CONAN: ON + # NODE_PACKAGE_TESTS_ONLY: ON + + # - name: conan-macos-x64-release-node + # build_node_package: true + # continue-on-error: true + # node: 20 + # runs-on: macos-13 # x86_64 + # BUILD_TYPE: Release + # CCOMPILER: clang + # CXXCOMPILER: clang++ + # CUCUMBER_TIMEOUT: 60000 + # ENABLE_ASSERTIONS: ON + # ENABLE_CONAN: ON + + # - name: conan-macos-arm64-release-node + # build_node_package: true + # continue-on-error: true + # node: 20 + # runs-on: macos-14 # arm64 + # BUILD_TYPE: Release + # CCOMPILER: clang + # CXXCOMPILER: clang++ + # CUCUMBER_TIMEOUT: 60000 + # ENABLE_ASSERTIONS: ON + # ENABLE_CONAN: ON name: ${{ matrix.name}} continue-on-error: ${{ matrix.continue-on-error }} @@ -652,7 +652,7 @@ jobs: benchmarks: if: github.event_name == 'pull_request' - needs: [format-taginfo-docs] + # needs: [format-taginfo-docs] runs-on: ubuntu-24.04 env: CCOMPILER: clang-16 @@ -774,9 +774,9 @@ jobs: ccache -p ccache -s - ci-complete: - runs-on: ubuntu-22.04 - needs: [build-test-publish, docker-image-matrix, windows-release-node, benchmarks] - steps: - - run: echo "CI complete" + # ci-complete: + # runs-on: ubuntu-22.04 + # needs: [build-test-publish, docker-image-matrix, windows-release-node, benchmarks] + # steps: + # - run: echo "CI complete" From 53032e556a4479d468b4cec986956abc7cd8620d Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Tue, 9 Jul 2024 22:53:24 +0200 Subject: [PATCH 13/47] wip --- include/contractor/contractor_heap.hpp | 3 ++- include/customizer/cell_customizer.hpp | 2 +- include/util/query_heap.hpp | 13 ++++++++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/include/contractor/contractor_heap.hpp b/include/contractor/contractor_heap.hpp index fc581f3b01b..77a0a85afbc 100644 --- a/include/contractor/contractor_heap.hpp +++ b/include/contractor/contractor_heap.hpp @@ -20,7 +20,8 @@ using ContractorHeap = util::QueryHeap>; + util::XORFastHashStorage, + false>; } // namespace osrm::contractor diff --git a/include/customizer/cell_customizer.hpp b/include/customizer/cell_customizer.hpp index 00d03163a7d..1e2072d7df2 100644 --- a/include/customizer/cell_customizer.hpp +++ b/include/customizer/cell_customizer.hpp @@ -25,7 +25,7 @@ class CellCustomizer public: using Heap = - util::QueryHeap>; + util::QueryHeap, false>; using HeapPtr = tbb::enumerable_thread_specific; CellCustomizer(const partitioner::MultiLevelPartition &partition) : partition(partition) {} diff --git a/include/util/query_heap.hpp b/include/util/query_heap.hpp index 83814a470af..77584c73a47 100644 --- a/include/util/query_heap.hpp +++ b/include/util/query_heap.hpp @@ -124,7 +124,7 @@ template class UnorderedMapStorage private: template using UnorderedMap = std:: - unordered_map, std::equal_to, PoolAllocator>>; + unordered_map, std::equal_to, PoolAllocator>*/>; UnorderedMap nodes; }; @@ -241,7 +241,8 @@ template > + typename IndexStorage = ArrayStorage, + bool ThreadLocal = true> class QueryHeap { private: @@ -259,11 +260,17 @@ class QueryHeap return weight > other.weight; } }; + + using AllocatorType = typename std::conditional, + std::allocator>::type; + + using HeapContainer = boost::heap::d_ary_heap, boost::heap::mutable_, boost::heap::compare>, - boost::heap::allocator>>; + boost::heap::allocator>; using HeapHandle = typename HeapContainer::handle_type; public: From 49f875c0f82c1f74e488207a74a8651b3a419651 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Wed, 10 Jul 2024 19:49:28 +0200 Subject: [PATCH 14/47] wip --- include/util/query_heap.hpp | 49 +------------------------------------ 1 file changed, 1 insertion(+), 48 deletions(-) diff --git a/include/util/query_heap.hpp b/include/util/query_heap.hpp index 77584c73a47..1240d52d219 100644 --- a/include/util/query_heap.hpp +++ b/include/util/query_heap.hpp @@ -124,7 +124,7 @@ template class UnorderedMapStorage private: template using UnorderedMap = std:: - unordered_map, std::equal_to, PoolAllocator>*/>; + unordered_map, std::equal_to, PoolAllocator>>; UnorderedMap nodes; }; @@ -190,53 +190,6 @@ class TwoLevelStorage OverlayIndexStorage overlay; }; -template class LoggingAllocator -{ - public: - using value_type = T; - - LoggingAllocator() noexcept = default; - template LoggingAllocator(const LoggingAllocator &) noexcept {} - - T *allocate(std::size_t n) - { - if (n == 1024) - { - std::cerr << "bingo\n"; - } - - auto p = std::allocator().allocate(n); - if (n != 1) - { - std::cout << "Allocated " << n << " element(s) of size " << sizeof(T) << " at " - << static_cast(p) << std::endl; - } - - return p; - } - - void deallocate(T *p, std::size_t n) noexcept - { - // std::cout << "Deallocated " << n << " element(s) at " << static_cast(p) << - // std::endl; - std::allocator().deallocate(p, n); - } - - template void construct(U *p, Args &&...args) - { - std::allocator a; - // std::cout << "Constructing object at " << static_cast(p) << std::endl; - std::allocator_traits>::construct(a, p, std::forward(args)...); - } - - template void destroy(U *p) - { - // std::cout << "Destroying object at " << static_cast(p) << std::endl; - std::allocator a; - std::allocator_traits>::destroy(a, p); - } -}; - template Date: Wed, 10 Jul 2024 20:16:37 +0200 Subject: [PATCH 15/47] wip --- include/contractor/contractor_heap.hpp | 3 +-- include/util/pool_allocator.hpp | 9 +++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/contractor/contractor_heap.hpp b/include/contractor/contractor_heap.hpp index 77a0a85afbc..fc581f3b01b 100644 --- a/include/contractor/contractor_heap.hpp +++ b/include/contractor/contractor_heap.hpp @@ -20,8 +20,7 @@ using ContractorHeap = util::QueryHeap, - false>; + util::XORFastHashStorage>; } // namespace osrm::contractor diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index 23b8737dbc0..6d4eaffa4bd 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -63,6 +63,15 @@ template class PoolAllocator } } + PoolAllocator(const PoolAllocator &) {} + + PoolAllocator &operator=(const PoolAllocator &){return *this;} + + // You may also want to implement move semantics if needed + PoolAllocator(PoolAllocator &&) noexcept = default; + PoolAllocator &operator=(PoolAllocator &&) noexcept = default; + + private: size_t get_next_power_of_two_exponent(size_t n) const { From 13448e4f9a7783abca3dcd3f98996ba082835505 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Wed, 10 Jul 2024 20:30:29 +0200 Subject: [PATCH 16/47] wip --- include/util/query_heap.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/util/query_heap.hpp b/include/util/query_heap.hpp index 1240d52d219..6f9ef54e1c1 100644 --- a/include/util/query_heap.hpp +++ b/include/util/query_heap.hpp @@ -124,7 +124,7 @@ template class UnorderedMapStorage private: template using UnorderedMap = std:: - unordered_map, std::equal_to, PoolAllocator>>; + unordered_map, std::equal_to, PoolAllocator>*/>; UnorderedMap nodes; }; From f9358ed0317963946750a1c9c0b8249c816e8baa Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Wed, 10 Jul 2024 21:13:50 +0200 Subject: [PATCH 17/47] wip --- include/util/pool_allocator.hpp | 3 +- unit_tests/util/pool_allocator.cpp | 73 ++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 unit_tests/util/pool_allocator.cpp diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index 6d4eaffa4bd..42bb5895268 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -82,8 +82,9 @@ template class PoolAllocator void allocate_block(size_t items_in_block) { items_in_block = std::max(items_in_block, MinItemsInBlock); + size_t block_size = items_in_block * sizeof(T); - T *block = static_cast(std::aligned_alloc(alignof(T), block_size)); + T *block = static_cast(std::malloc(block_size)); if (!block) { throw std::bad_alloc(); diff --git a/unit_tests/util/pool_allocator.cpp b/unit_tests/util/pool_allocator.cpp new file mode 100644 index 00000000000..2d86161d0e4 --- /dev/null +++ b/unit_tests/util/pool_allocator.cpp @@ -0,0 +1,73 @@ +#include "util/pool_allocator.hpp" +#include "util/typedefs.hpp" +#include + +#include + +BOOST_AUTO_TEST_SUITE(pool_allocator) + +using namespace osrm; +using namespace osrm::util; + +// in many of these tests we hope on address sanitizer to alert in the case if we are doing something wrong +BOOST_AUTO_TEST_CASE(smoke) +{ + PoolAllocator pool; + auto ptr = pool.allocate(1); + *ptr = 42; + BOOST_CHECK_NE(ptr, nullptr); + pool.deallocate(ptr, 1); + + ptr = pool.allocate(2); + *ptr = 42; + *(ptr + 1) = 43; + BOOST_CHECK_NE(ptr, nullptr); + pool.deallocate(ptr, 2); +} + +BOOST_AUTO_TEST_CASE(a_lot_of_items) +{ + PoolAllocator pool; + auto ptr = pool.allocate(2048); + for (int i = 0; i < 2048; ++i) + { + ptr[i] = i; + } + + for (int i = 0; i < 2048; ++i) + { + BOOST_CHECK_EQUAL(ptr[i], i); + } + + pool.deallocate(ptr, 2048); +} + +BOOST_AUTO_TEST_CASE(copy) +{ + PoolAllocator pool; + auto ptr = pool.allocate(1); + *ptr = 42; + BOOST_CHECK_NE(ptr, nullptr); + pool.deallocate(ptr, 1); + + PoolAllocator pool2(pool); + ptr = pool2.allocate(1); + *ptr = 42; + BOOST_CHECK_NE(ptr, nullptr); + pool2.deallocate(ptr, 1); +} + +BOOST_AUTO_TEST_CASE(unordered_map) +{ + std::unordered_map, std::equal_to, PoolAllocator>> map; + map[1] = 42; + BOOST_CHECK_EQUAL(map[1], 42); + + map.clear(); + + map[2] = 43; + + BOOST_CHECK_EQUAL(map[2], 43); +} + +BOOST_AUTO_TEST_SUITE_END() From 1037256a30a69bfb7942186b132b1e07e8382d27 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Wed, 10 Jul 2024 21:49:40 +0200 Subject: [PATCH 18/47] wip --- include/util/pool_allocator.hpp | 40 ++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index 42bb5895268..94e045e3d41 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -63,16 +63,44 @@ template class PoolAllocator } } - PoolAllocator(const PoolAllocator &) {} + PoolAllocator(const PoolAllocator &) = delete; + PoolAllocator &operator=(const PoolAllocator &) = delete; + + PoolAllocator(PoolAllocator &&other) noexcept + : free_lists_(std::move(other.free_lists_)), + blocks_(std::move(other.blocks_)), + current_block_ptr_(other.current_block_ptr_), + current_block_left_items_(other.current_block_left_items_), + total_allocated_(other.total_allocated_) + { + other.current_block_ptr_ = nullptr; + other.current_block_left_items_ = 0; + other.total_allocated_ = 0; + } - PoolAllocator &operator=(const PoolAllocator &){return *this;} + PoolAllocator &operator=(PoolAllocator &&other) noexcept + { + if (this != &other) + { + for (auto block : blocks_) + { + std::free(block); + } - // You may also want to implement move semantics if needed - PoolAllocator(PoolAllocator &&) noexcept = default; - PoolAllocator &operator=(PoolAllocator &&) noexcept = default; + free_lists_ = std::move(other.free_lists_); + blocks_ = std::move(other.blocks_); + current_block_ptr_ = other.current_block_ptr_; + current_block_left_items_ = other.current_block_left_items_; + total_allocated_ = other.total_allocated_; + other.current_block_ptr_ = nullptr; + other.current_block_left_items_ = 0; + other.total_allocated_ = 0; + } + return *this; + } - private: +private: size_t get_next_power_of_two_exponent(size_t n) const { BOOST_ASSERT(n > 0); From 6f04aa9587d99b3e75a473ebbb1f0a996cacea1a Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Wed, 10 Jul 2024 22:01:25 +0200 Subject: [PATCH 19/47] wip --- include/util/pool_allocator.hpp | 108 ++++++++++++++++------------- unit_tests/util/pool_allocator.cpp | 15 ++++ 2 files changed, 73 insertions(+), 50 deletions(-) diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index 94e045e3d41..f082b7782aa 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -13,19 +13,18 @@ namespace osrm::util { #if 1 -template class PoolAllocator -{ - public: - using value_type = T; - - PoolAllocator() noexcept = default; +template +class PoolAllocator; - template PoolAllocator(const PoolAllocator &) noexcept {} - - template struct rebind +template +class MemoryManager +{ +public: + static MemoryManager &instance() { - using other = PoolAllocator; - }; + thread_local MemoryManager instance; + return instance; + } T *allocate(std::size_t n) { @@ -55,7 +54,7 @@ template class PoolAllocator free_lists_[free_list_index].push_back(p); } - ~PoolAllocator() + ~MemoryManager() { for (auto block : blocks_) { @@ -63,44 +62,11 @@ template class PoolAllocator } } - PoolAllocator(const PoolAllocator &) = delete; - PoolAllocator &operator=(const PoolAllocator &) = delete; - - PoolAllocator(PoolAllocator &&other) noexcept - : free_lists_(std::move(other.free_lists_)), - blocks_(std::move(other.blocks_)), - current_block_ptr_(other.current_block_ptr_), - current_block_left_items_(other.current_block_left_items_), - total_allocated_(other.total_allocated_) - { - other.current_block_ptr_ = nullptr; - other.current_block_left_items_ = 0; - other.total_allocated_ = 0; - } - - PoolAllocator &operator=(PoolAllocator &&other) noexcept - { - if (this != &other) - { - for (auto block : blocks_) - { - std::free(block); - } - - free_lists_ = std::move(other.free_lists_); - blocks_ = std::move(other.blocks_); - current_block_ptr_ = other.current_block_ptr_; - current_block_left_items_ = other.current_block_left_items_; - total_allocated_ = other.total_allocated_; - - other.current_block_ptr_ = nullptr; - other.current_block_left_items_ = 0; - other.total_allocated_ = 0; - } - return *this; - } - private: + MemoryManager() = default; + MemoryManager(const MemoryManager &) = delete; + MemoryManager &operator=(const MemoryManager &) = delete; + size_t get_next_power_of_two_exponent(size_t n) const { BOOST_ASSERT(n > 0); @@ -110,7 +76,7 @@ template class PoolAllocator void allocate_block(size_t items_in_block) { items_in_block = std::max(items_in_block, MinItemsInBlock); - + size_t block_size = items_in_block * sizeof(T); T *block = static_cast(std::malloc(block_size)); if (!block) @@ -131,6 +97,48 @@ template class PoolAllocator size_t total_allocated_ = 0; }; +template +class PoolAllocator +{ +public: + using value_type = T; + + PoolAllocator() noexcept = default; + + template + PoolAllocator(const PoolAllocator &) noexcept {} + + template + struct rebind + { + using other = PoolAllocator; + }; + + T *allocate(std::size_t n) + { + return MemoryManager::instance().allocate(n); + } + + void deallocate(T *p, std::size_t n) noexcept + { + MemoryManager::instance().deallocate(p, n); + } + + ~PoolAllocator() = default; + + PoolAllocator(const PoolAllocator &) = default; + PoolAllocator &operator=(const PoolAllocator &) = default; + PoolAllocator(PoolAllocator &&) noexcept = default; + PoolAllocator &operator=(PoolAllocator &&) noexcept = default; + +private: + static size_t get_next_power_of_two_exponent(size_t n) + { + BOOST_ASSERT(n > 0); + return (sizeof(size_t) * 8) - std::countl_zero(n - 1); + } +}; + template bool operator==(const PoolAllocator &, const PoolAllocator &) { diff --git a/unit_tests/util/pool_allocator.cpp b/unit_tests/util/pool_allocator.cpp index 2d86161d0e4..21cff54a39b 100644 --- a/unit_tests/util/pool_allocator.cpp +++ b/unit_tests/util/pool_allocator.cpp @@ -57,6 +57,21 @@ BOOST_AUTO_TEST_CASE(copy) pool2.deallocate(ptr, 1); } +BOOST_AUTO_TEST_CASE(move) +{ + PoolAllocator pool; + auto ptr = pool.allocate(1); + *ptr = 42; + BOOST_CHECK_NE(ptr, nullptr); + pool.deallocate(ptr, 1); + + PoolAllocator pool2(std::move(pool)); + ptr = pool2.allocate(1); + *ptr = 42; + BOOST_CHECK_NE(ptr, nullptr); + pool2.deallocate(ptr, 1); +} + BOOST_AUTO_TEST_CASE(unordered_map) { std::unordered_map, std::equal_to, PoolAllocator>> map; From 6d2fc45476592a611451af0789fc46eeec46dab5 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Wed, 10 Jul 2024 22:12:59 +0200 Subject: [PATCH 20/47] wip --- test/data/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/data/Makefile b/test/data/Makefile index 2c617405b9a..8d0748b546b 100755 --- a/test/data/Makefile +++ b/test/data/Makefile @@ -65,4 +65,4 @@ benchmark: data $(DATA_NAME).requests checksum: $(MD5SUM) $(DATA_NAME).osm.pbf $(DATA_NAME).poly > data.md5sum -.PHONY: clean checksum benchmark data +.PHONY: clean checksum data From abbe5e25a5179b8039af8d0db5ce848fba4a8c4b Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 11 Jul 2024 18:05:16 +0200 Subject: [PATCH 21/47] wip --- include/util/pool_allocator.hpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index f082b7782aa..48115a5168d 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -28,6 +29,7 @@ class MemoryManager T *allocate(std::size_t n) { + std::lock_guard lock(mutex_); size_t free_list_index = get_next_power_of_two_exponent(n); auto &free_list = free_lists_[free_list_index]; const auto items_in_block = 1u << free_list_index; @@ -50,19 +52,23 @@ class MemoryManager void deallocate(T *p, std::size_t n) noexcept { + std::lock_guard lock(mutex_); size_t free_list_index = get_next_power_of_two_exponent(n); free_lists_[free_list_index].push_back(p); } ~MemoryManager() { - for (auto block : blocks_) - { - std::free(block); - } + // std::lock_guard lock(mutex_); + // for (auto block : blocks_) + // { + // std::free(block); + // } } private: + std::mutex mutex_; + MemoryManager() = default; MemoryManager(const MemoryManager &) = delete; MemoryManager &operator=(const MemoryManager &) = delete; From 7337771aaf0ec07919d4ee5a00ecc33dacfd955d Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 11 Jul 2024 18:16:07 +0200 Subject: [PATCH 22/47] wip --- include/util/pool_allocator.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index 48115a5168d..e106c575f3c 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -59,11 +59,11 @@ class MemoryManager ~MemoryManager() { - // std::lock_guard lock(mutex_); - // for (auto block : blocks_) - // { - // std::free(block); - // } + // std::lock_guard lock(mutex_); + for (auto block : blocks_) + { + std::free(block); + } } private: From 058c26e39a3b8ff9748458e44e696cf8077b5b92 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 11 Jul 2024 18:21:20 +0200 Subject: [PATCH 23/47] wip --- include/engine/search_engine_data.hpp | 38 +++++++++++++-------------- include/util/pool_allocator.hpp | 1 - src/engine/search_engine_data.cpp | 28 ++++++++++---------- 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/include/engine/search_engine_data.hpp b/include/engine/search_engine_data.hpp index 16ffa25b132..7c885343f34 100644 --- a/include/engine/search_engine_data.hpp +++ b/include/engine/search_engine_data.hpp @@ -45,19 +45,19 @@ template <> struct SearchEngineData ManyToManyHeapData, util::UnorderedMapStorage>; - using SearchEngineHeapPtr = boost::thread_specific_ptr; + using SearchEngineHeapPtr = std::unique_ptr; - using ManyToManyHeapPtr = boost::thread_specific_ptr; + using ManyToManyHeapPtr = std::unique_ptr; - static SearchEngineHeapPtr forward_heap_1; - static SearchEngineHeapPtr reverse_heap_1; - static SearchEngineHeapPtr forward_heap_2; - static SearchEngineHeapPtr reverse_heap_2; - static SearchEngineHeapPtr forward_heap_3; - static SearchEngineHeapPtr reverse_heap_3; - static ManyToManyHeapPtr many_to_many_heap; - static SearchEngineHeapPtr map_matching_forward_heap_1; - static SearchEngineHeapPtr map_matching_reverse_heap_1; + static thread_local SearchEngineHeapPtr forward_heap_1; + static thread_local SearchEngineHeapPtr reverse_heap_1; + static thread_local SearchEngineHeapPtr forward_heap_2; + static thread_local SearchEngineHeapPtr reverse_heap_2; + static thread_local SearchEngineHeapPtr forward_heap_3; + static thread_local SearchEngineHeapPtr reverse_heap_3; + static thread_local ManyToManyHeapPtr many_to_many_heap; + static thread_local SearchEngineHeapPtr map_matching_forward_heap_1; + static thread_local SearchEngineHeapPtr map_matching_reverse_heap_1; void InitializeOrClearMapMatchingThreadLocalStorage(unsigned number_of_nodes); @@ -127,16 +127,16 @@ template <> struct SearchEngineData MapMatchingMultiLayerDijkstraHeapData, util::TwoLevelStorage>; - using SearchEngineHeapPtr = boost::thread_specific_ptr; - using ManyToManyHeapPtr = boost::thread_specific_ptr; - using MapMatchingHeapPtr = boost::thread_specific_ptr; + using SearchEngineHeapPtr = std::unique_ptr; + using ManyToManyHeapPtr = std::unique_ptr; + using MapMatchingHeapPtr = std::unique_ptr; - static SearchEngineHeapPtr forward_heap_1; - static SearchEngineHeapPtr reverse_heap_1; - static MapMatchingHeapPtr map_matching_forward_heap_1; - static MapMatchingHeapPtr map_matching_reverse_heap_1; + static thread_local SearchEngineHeapPtr forward_heap_1; + static thread_local SearchEngineHeapPtr reverse_heap_1; + static thread_local MapMatchingHeapPtr map_matching_forward_heap_1; + static thread_local MapMatchingHeapPtr map_matching_reverse_heap_1; - static ManyToManyHeapPtr many_to_many_heap; + static thread_local ManyToManyHeapPtr many_to_many_heap; void InitializeOrClearFirstThreadLocalStorage(unsigned number_of_nodes, unsigned number_of_boundary_nodes); diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index e106c575f3c..7d6e0371412 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -59,7 +59,6 @@ class MemoryManager ~MemoryManager() { - // std::lock_guard lock(mutex_); for (auto block : blocks_) { std::free(block); diff --git a/src/engine/search_engine_data.cpp b/src/engine/search_engine_data.cpp index dd1a053e0e6..1eb497a469d 100644 --- a/src/engine/search_engine_data.cpp +++ b/src/engine/search_engine_data.cpp @@ -5,16 +5,16 @@ namespace osrm::engine // CH heaps using CH = routing_algorithms::ch::Algorithm; -SearchEngineData::SearchEngineHeapPtr SearchEngineData::forward_heap_1; -SearchEngineData::SearchEngineHeapPtr SearchEngineData::reverse_heap_1; -SearchEngineData::SearchEngineHeapPtr SearchEngineData::forward_heap_2; -SearchEngineData::SearchEngineHeapPtr SearchEngineData::reverse_heap_2; -SearchEngineData::SearchEngineHeapPtr SearchEngineData::forward_heap_3; -SearchEngineData::SearchEngineHeapPtr SearchEngineData::reverse_heap_3; -SearchEngineData::SearchEngineHeapPtr SearchEngineData::map_matching_forward_heap_1; -SearchEngineData::SearchEngineHeapPtr SearchEngineData::map_matching_reverse_heap_1; +thread_local SearchEngineData::SearchEngineHeapPtr SearchEngineData::forward_heap_1; +thread_local SearchEngineData::SearchEngineHeapPtr SearchEngineData::reverse_heap_1; +thread_local SearchEngineData::SearchEngineHeapPtr SearchEngineData::forward_heap_2; +thread_local SearchEngineData::SearchEngineHeapPtr SearchEngineData::reverse_heap_2; +thread_local SearchEngineData::SearchEngineHeapPtr SearchEngineData::forward_heap_3; +thread_local SearchEngineData::SearchEngineHeapPtr SearchEngineData::reverse_heap_3; +thread_local SearchEngineData::SearchEngineHeapPtr SearchEngineData::map_matching_forward_heap_1; +thread_local SearchEngineData::SearchEngineHeapPtr SearchEngineData::map_matching_reverse_heap_1; -SearchEngineData::ManyToManyHeapPtr SearchEngineData::many_to_many_heap; +thread_local SearchEngineData::ManyToManyHeapPtr SearchEngineData::many_to_many_heap; void SearchEngineData::InitializeOrClearMapMatchingThreadLocalStorage(unsigned number_of_nodes) { @@ -114,11 +114,11 @@ void SearchEngineData::InitializeOrClearManyToManyThreadLocalStorage(unsigne // MLD using MLD = routing_algorithms::mld::Algorithm; -SearchEngineData::SearchEngineHeapPtr SearchEngineData::forward_heap_1; -SearchEngineData::SearchEngineHeapPtr SearchEngineData::reverse_heap_1; -SearchEngineData::MapMatchingHeapPtr SearchEngineData::map_matching_forward_heap_1; -SearchEngineData::MapMatchingHeapPtr SearchEngineData::map_matching_reverse_heap_1; -SearchEngineData::ManyToManyHeapPtr SearchEngineData::many_to_many_heap; +thread_local SearchEngineData::SearchEngineHeapPtr SearchEngineData::forward_heap_1; +thread_local SearchEngineData::SearchEngineHeapPtr SearchEngineData::reverse_heap_1; +thread_local SearchEngineData::MapMatchingHeapPtr SearchEngineData::map_matching_forward_heap_1; +thread_local SearchEngineData::MapMatchingHeapPtr SearchEngineData::map_matching_reverse_heap_1; +thread_local SearchEngineData::ManyToManyHeapPtr SearchEngineData::many_to_many_heap; void SearchEngineData::InitializeOrClearMapMatchingThreadLocalStorage( unsigned number_of_nodes, unsigned number_of_boundary_nodes) From c5aae5148e74bf40f50506d3a67d1488196ec3fd Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 11 Jul 2024 19:33:45 +0200 Subject: [PATCH 24/47] wip --- include/contractor/contractor_heap.hpp | 3 ++- include/util/pool_allocator.hpp | 6 +----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/include/contractor/contractor_heap.hpp b/include/contractor/contractor_heap.hpp index fc581f3b01b..77a0a85afbc 100644 --- a/include/contractor/contractor_heap.hpp +++ b/include/contractor/contractor_heap.hpp @@ -20,7 +20,8 @@ using ContractorHeap = util::QueryHeap>; + util::XORFastHashStorage, + false>; } // namespace osrm::contractor diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index 7d6e0371412..9789e26e171 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -23,13 +23,12 @@ class MemoryManager public: static MemoryManager &instance() { - thread_local MemoryManager instance; + static thread_local MemoryManager instance; return instance; } T *allocate(std::size_t n) { - std::lock_guard lock(mutex_); size_t free_list_index = get_next_power_of_two_exponent(n); auto &free_list = free_lists_[free_list_index]; const auto items_in_block = 1u << free_list_index; @@ -52,7 +51,6 @@ class MemoryManager void deallocate(T *p, std::size_t n) noexcept { - std::lock_guard lock(mutex_); size_t free_list_index = get_next_power_of_two_exponent(n); free_lists_[free_list_index].push_back(p); } @@ -66,8 +64,6 @@ class MemoryManager } private: - std::mutex mutex_; - MemoryManager() = default; MemoryManager(const MemoryManager &) = delete; MemoryManager &operator=(const MemoryManager &) = delete; From 4d940ab09673937d67a4e7f2b6acfe6d1aa5c3f1 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 11 Jul 2024 20:05:08 +0200 Subject: [PATCH 25/47] wip --- include/util/pool_allocator.hpp | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index 9789e26e171..4758c8210ec 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -14,6 +14,26 @@ namespace osrm::util { #if 1 + +class Cleanup { +public: + static void CleanupAtExit(void* p) { + std::lock_guard lock(mutex_); + allocated_blocks_.push_back(static_cast(p)); + } + + ~Cleanup() { + std::lock_guard lock(mutex_); + for (auto block : allocated_blocks_) { + std::free(block); + } + } + +private: + static std::vector allocated_blocks_; + static std::mutex mutex_; +}; + template class PoolAllocator; @@ -57,12 +77,12 @@ class MemoryManager ~MemoryManager() { - for (auto block : blocks_) - { - std::free(block); - } + // std::cerr << "~MemoryManager()" << std::endl; + // for (auto block : blocks_) + // { + // std::free(block); + // } } - private: MemoryManager() = default; MemoryManager(const MemoryManager &) = delete; @@ -84,6 +104,8 @@ class MemoryManager { throw std::bad_alloc(); } + Cleanup::CleanupAtExit(block); + total_allocated_ += block_size; blocks_.push_back(block); current_block_ptr_ = block; From 3691f90e23305ed49eb19ab043fe0e8e355d0996 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 11 Jul 2024 20:11:11 +0200 Subject: [PATCH 26/47] wip --- src/util/pool_allocator.cpp | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/util/pool_allocator.cpp diff --git a/src/util/pool_allocator.cpp b/src/util/pool_allocator.cpp new file mode 100644 index 00000000000..5a4cd5b70f4 --- /dev/null +++ b/src/util/pool_allocator.cpp @@ -0,0 +1,7 @@ +#include "util/pool_allocator.hpp" + +namespace osrm::util +{ + std::vector Cleanup::allocated_blocks_; + std::mutex Cleanup::mutex_; +} // namespace osrm::util \ No newline at end of file From 18b3c5f8ed3651f326256e064e613813482c5f12 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 11 Jul 2024 20:25:55 +0200 Subject: [PATCH 27/47] wip --- include/util/pool_allocator.hpp | 21 --------------------- src/util/pool_allocator.cpp | 2 -- 2 files changed, 23 deletions(-) diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index 4758c8210ec..0c96c080860 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -15,25 +15,6 @@ namespace osrm::util #if 1 -class Cleanup { -public: - static void CleanupAtExit(void* p) { - std::lock_guard lock(mutex_); - allocated_blocks_.push_back(static_cast(p)); - } - - ~Cleanup() { - std::lock_guard lock(mutex_); - for (auto block : allocated_blocks_) { - std::free(block); - } - } - -private: - static std::vector allocated_blocks_; - static std::mutex mutex_; -}; - template class PoolAllocator; @@ -104,8 +85,6 @@ class MemoryManager { throw std::bad_alloc(); } - Cleanup::CleanupAtExit(block); - total_allocated_ += block_size; blocks_.push_back(block); current_block_ptr_ = block; diff --git a/src/util/pool_allocator.cpp b/src/util/pool_allocator.cpp index 5a4cd5b70f4..4b55e524cf9 100644 --- a/src/util/pool_allocator.cpp +++ b/src/util/pool_allocator.cpp @@ -2,6 +2,4 @@ namespace osrm::util { - std::vector Cleanup::allocated_blocks_; - std::mutex Cleanup::mutex_; } // namespace osrm::util \ No newline at end of file From 9ef1911eae6293591c3d89d7bf111a4f14a3c6fa Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 11 Jul 2024 20:42:47 +0200 Subject: [PATCH 28/47] wip --- include/util/pool_allocator.hpp | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index 0c96c080860..0b48adf165e 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -22,9 +22,13 @@ template class MemoryManager { public: - static MemoryManager &instance() + static std::shared_ptr instance() { - static thread_local MemoryManager instance; + static thread_local std::shared_ptr instance; + if (!instance) + { + instance = std::shared_ptr(new MemoryManager()); + } return instance; } @@ -58,11 +62,11 @@ class MemoryManager ~MemoryManager() { - // std::cerr << "~MemoryManager()" << std::endl; - // for (auto block : blocks_) - // { - // std::free(block); - // } + // std::cerr << "~MemoryManager()" << std::endl; + for (auto block : blocks_) + { + std::free(block); + } } private: MemoryManager() = default; @@ -105,10 +109,10 @@ class PoolAllocator public: using value_type = T; - PoolAllocator() noexcept = default; + PoolAllocator() noexcept : pool(MemoryManager::instance()) {}; template - PoolAllocator(const PoolAllocator &) noexcept {} + PoolAllocator(const PoolAllocator &) noexcept : pool(MemoryManager::instance()) {} template struct rebind @@ -118,12 +122,12 @@ class PoolAllocator T *allocate(std::size_t n) { - return MemoryManager::instance().allocate(n); + return pool->allocate(n); } void deallocate(T *p, std::size_t n) noexcept { - MemoryManager::instance().deallocate(p, n); + pool->deallocate(p, n); } ~PoolAllocator() = default; @@ -134,6 +138,8 @@ class PoolAllocator PoolAllocator &operator=(PoolAllocator &&) noexcept = default; private: + std::shared_ptr> pool; + static size_t get_next_power_of_two_exponent(size_t n) { BOOST_ASSERT(n > 0); From a90e9dde3339989fac0463f63751cb64fe6e2914 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 11 Jul 2024 20:47:20 +0200 Subject: [PATCH 29/47] wip --- include/util/pool_allocator.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index 0b48adf165e..fc2d71b0655 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace osrm::util { From 434cab4952db1adf9df219cec71525c2750ba448 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 11 Jul 2024 20:54:00 +0200 Subject: [PATCH 30/47] wip --- include/contractor/contractor_heap.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/contractor/contractor_heap.hpp b/include/contractor/contractor_heap.hpp index 77a0a85afbc..fc581f3b01b 100644 --- a/include/contractor/contractor_heap.hpp +++ b/include/contractor/contractor_heap.hpp @@ -20,8 +20,7 @@ using ContractorHeap = util::QueryHeap, - false>; + util::XORFastHashStorage>; } // namespace osrm::contractor From a18ad919af9ccc4d327cc4a30d05f2e099bd644a Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 11 Jul 2024 21:06:03 +0200 Subject: [PATCH 31/47] wip --- include/customizer/cell_customizer.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/customizer/cell_customizer.hpp b/include/customizer/cell_customizer.hpp index 1e2072d7df2..00d03163a7d 100644 --- a/include/customizer/cell_customizer.hpp +++ b/include/customizer/cell_customizer.hpp @@ -25,7 +25,7 @@ class CellCustomizer public: using Heap = - util::QueryHeap, false>; + util::QueryHeap>; using HeapPtr = tbb::enumerable_thread_specific; CellCustomizer(const partitioner::MultiLevelPartition &partition) : partition(partition) {} From 69bc6c035d8a377ff3ef2ea88c2fbf0b2ce614ee Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 11 Jul 2024 21:26:19 +0200 Subject: [PATCH 32/47] wip --- include/customizer/cell_customizer.hpp | 8 +++++--- include/util/query_heap.hpp | 3 +++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/include/customizer/cell_customizer.hpp b/include/customizer/cell_customizer.hpp index 00d03163a7d..dfb927cdd3f 100644 --- a/include/customizer/cell_customizer.hpp +++ b/include/customizer/cell_customizer.hpp @@ -116,15 +116,17 @@ class CellCustomizer const std::vector &allowed_nodes, CellMetric &metric) const { - Heap heap_exemplar(graph.GetNumberOfNodes()); - HeapPtr heaps(heap_exemplar); + // std::cerr << "Customizing cells\n"; + // Heap heap_exemplar(graph.GetNumberOfNodes()); + // HeapPtr heaps(heap_exemplar); for (std::size_t level = 1; level < partition.GetNumberOfLevels(); ++level) { tbb::parallel_for(tbb::blocked_range(0, partition.GetNumberOfCells(level)), [&](const tbb::blocked_range &range) { - auto &heap = heaps.local(); + Heap heap{graph.GetNumberOfNodes()}; + // auto &heap = heaps.local(); for (auto id = range.begin(), end = range.end(); id != end; ++id) { Customize( diff --git a/include/util/query_heap.hpp b/include/util/query_heap.hpp index 6f9ef54e1c1..c79ffc19b6a 100644 --- a/include/util/query_heap.hpp +++ b/include/util/query_heap.hpp @@ -238,6 +238,9 @@ class QueryHeap Data data; }; + QueryHeap(const QueryHeap& other) = delete; + QueryHeap(QueryHeap&& other) = delete; + template explicit QueryHeap(StorageArgs... args) : node_index(args...) { Clear(); From fb8182a10eb0e6adfa0c8c20a8745cf1bcc4d3fa Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 11 Jul 2024 21:40:00 +0200 Subject: [PATCH 33/47] wip --- include/customizer/cell_customizer.hpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/customizer/cell_customizer.hpp b/include/customizer/cell_customizer.hpp index dfb927cdd3f..d92bd411e3b 100644 --- a/include/customizer/cell_customizer.hpp +++ b/include/customizer/cell_customizer.hpp @@ -117,16 +117,17 @@ class CellCustomizer CellMetric &metric) const { // std::cerr << "Customizing cells\n"; - // Heap heap_exemplar(graph.GetNumberOfNodes()); - // HeapPtr heaps(heap_exemplar); + const auto number_of_nodes = graph.GetNumberOfNodes(); + HeapPtr heaps([number_of_nodes]{ + return Heap{number_of_nodes}; + }); for (std::size_t level = 1; level < partition.GetNumberOfLevels(); ++level) { tbb::parallel_for(tbb::blocked_range(0, partition.GetNumberOfCells(level)), [&](const tbb::blocked_range &range) { - Heap heap{graph.GetNumberOfNodes()}; - // auto &heap = heaps.local(); + auto &heap = heaps.local(); for (auto id = range.begin(), end = range.end(); id != end; ++id) { Customize( From 270f187e2aad578ec9b47ca70075e5627af031d9 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 11 Jul 2024 22:32:41 +0200 Subject: [PATCH 34/47] wip --- include/util/meminfo.hpp | 16 +++++++++++++--- include/util/pool_allocator.hpp | 29 ++++++++++------------------- include/util/query_heap.hpp | 8 ++------ src/benchmarks/bench.cpp | 4 +++- test/data/Makefile | 2 +- 5 files changed, 29 insertions(+), 30 deletions(-) diff --git a/include/util/meminfo.hpp b/include/util/meminfo.hpp index e2059975150..4c3e16f0b7a 100644 --- a/include/util/meminfo.hpp +++ b/include/util/meminfo.hpp @@ -2,6 +2,7 @@ #define MEMINFO_HPP #include "util/log.hpp" +#include #ifndef _WIN32 #include @@ -10,18 +11,27 @@ namespace osrm::util { -inline void DumpMemoryStats() +inline size_t PeakRAMUsedInBytes() { #ifndef _WIN32 rusage usage; getrusage(RUSAGE_SELF, &usage); #ifdef __linux__ // Under linux, ru.maxrss is in kb - util::Log() << "RAM: peak bytes used: " << usage.ru_maxrss * 1024; + return usage.ru_maxrss * 1024; #else // __linux__ // Under BSD systems (OSX), it's in bytes - util::Log() << "RAM: peak bytes used: " << usage.ru_maxrss; + return usage.ru_maxrss; #endif // __linux__ +#else // _WIN32 + return 0; +#endif // _WIN32 +} + +inline void DumpMemoryStats() +{ +#ifndef _WIN32 + util::Log() << "RAM: peak bytes used: " << PeakRAMUsedInBytes(); #else // _WIN32 util::Log() << "RAM: peak bytes used: "; #endif // _WIN32 diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index fc2d71b0655..a0203b941a9 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -14,14 +14,14 @@ namespace osrm::util { -#if 1 - -template +template class PoolAllocator; -template +template class MemoryManager { +private: + constexpr static size_t MIN_ITEMS_IN_BLOCK = 1024; public: static std::shared_ptr instance() { @@ -82,7 +82,7 @@ class MemoryManager void allocate_block(size_t items_in_block) { - items_in_block = std::max(items_in_block, MinItemsInBlock); + items_in_block = std::max(items_in_block, MIN_ITEMS_IN_BLOCK); size_t block_size = items_in_block * sizeof(T); T *block = static_cast(std::malloc(block_size)); @@ -104,21 +104,21 @@ class MemoryManager size_t total_allocated_ = 0; }; -template +template class PoolAllocator { public: using value_type = T; - PoolAllocator() noexcept : pool(MemoryManager::instance()) {}; + PoolAllocator() noexcept : pool(MemoryManager::instance()) {}; template - PoolAllocator(const PoolAllocator &) noexcept : pool(MemoryManager::instance()) {} + PoolAllocator(const PoolAllocator &) noexcept : pool(MemoryManager::instance()) {} template struct rebind { - using other = PoolAllocator; + using other = PoolAllocator; }; T *allocate(std::size_t n) @@ -139,13 +139,7 @@ class PoolAllocator PoolAllocator &operator=(PoolAllocator &&) noexcept = default; private: - std::shared_ptr> pool; - - static size_t get_next_power_of_two_exponent(size_t n) - { - BOOST_ASSERT(n > 0); - return (sizeof(size_t) * 8) - std::countl_zero(n - 1); - } + std::shared_ptr> pool; }; template @@ -160,7 +154,4 @@ bool operator!=(const PoolAllocator &, const PoolAllocator &) return false; } -#else -template using PoolAllocator = std::allocator; -#endif } // namespace osrm::util diff --git a/include/util/query_heap.hpp b/include/util/query_heap.hpp index c79ffc19b6a..44f18355334 100644 --- a/include/util/query_heap.hpp +++ b/include/util/query_heap.hpp @@ -194,8 +194,7 @@ template , - bool ThreadLocal = true> + typename IndexStorage = ArrayStorage> class QueryHeap { private: @@ -214,16 +213,13 @@ class QueryHeap } }; - using AllocatorType = typename std::conditional, - std::allocator>::type; using HeapContainer = boost::heap::d_ary_heap, boost::heap::mutable_, boost::heap::compare>, - boost::heap::allocator>; + boost::heap::allocator>>; using HeapHandle = typename HeapContainer::handle_type; public: diff --git a/src/benchmarks/bench.cpp b/src/benchmarks/bench.cpp index 019ff645659..2bf62905e9a 100644 --- a/src/benchmarks/bench.cpp +++ b/src/benchmarks/bench.cpp @@ -12,7 +12,7 @@ #include "osrm/coordinate.hpp" #include "osrm/engine_config.hpp" #include "osrm/json_container.hpp" - +#include "util/meminfo.hpp" #include "osrm/osrm.hpp" #include "osrm/status.hpp" @@ -655,6 +655,8 @@ try std::cerr << "Unknown benchmark: " << benchmarkToRun << std::endl; return EXIT_FAILURE; } + + std::cerr << "Peak RAM: " << osrm::util::PeakRAMUsedInBytes() / (1024 * 1024) << "MB" << std::endl; return EXIT_SUCCESS; } catch (const std::exception &e) diff --git a/test/data/Makefile b/test/data/Makefile index 8d0748b546b..b79e87fe0e2 100755 --- a/test/data/Makefile +++ b/test/data/Makefile @@ -65,4 +65,4 @@ benchmark: data $(DATA_NAME).requests checksum: $(MD5SUM) $(DATA_NAME).osm.pbf $(DATA_NAME).poly > data.md5sum -.PHONY: clean checksum data +.PHONY: clean checksum benchmark data \ No newline at end of file From e9cdb317f61d3917663859f39abd1ad489c6327e Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 11 Jul 2024 22:39:31 +0200 Subject: [PATCH 35/47] wip --- unit_tests/util/pool_allocator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unit_tests/util/pool_allocator.cpp b/unit_tests/util/pool_allocator.cpp index 21cff54a39b..215cdebd5c1 100644 --- a/unit_tests/util/pool_allocator.cpp +++ b/unit_tests/util/pool_allocator.cpp @@ -27,7 +27,7 @@ BOOST_AUTO_TEST_CASE(smoke) BOOST_AUTO_TEST_CASE(a_lot_of_items) { - PoolAllocator pool; + PoolAllocator pool; auto ptr = pool.allocate(2048); for (int i = 0; i < 2048; ++i) { From ac05d36102dd4ecd7579863801a55d9f0c2b719b Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 11 Jul 2024 23:05:45 +0200 Subject: [PATCH 36/47] Update bench.cpp --- src/benchmarks/bench.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/benchmarks/bench.cpp b/src/benchmarks/bench.cpp index 2bf62905e9a..45ef1d8faae 100644 --- a/src/benchmarks/bench.cpp +++ b/src/benchmarks/bench.cpp @@ -656,7 +656,7 @@ try return EXIT_FAILURE; } - std::cerr << "Peak RAM: " << osrm::util::PeakRAMUsedInBytes() / (1024 * 1024) << "MB" << std::endl; + std::cout << "Peak RAM: " << osrm::util::PeakRAMUsedInBytes() / (1024 * 1024) << "MB" << std::endl; return EXIT_SUCCESS; } catch (const std::exception &e) From e045dea04cfe0fc421abe967dc615f3cbc97a1ef Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 11 Jul 2024 23:21:48 +0200 Subject: [PATCH 37/47] Use pool in std::unordered_map --- include/util/pool_allocator.hpp | 46 +++++++++++++++++---------------- include/util/query_heap.hpp | 6 ++++- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index a0203b941a9..9015d111e5d 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -14,14 +14,11 @@ namespace osrm::util { -template -class PoolAllocator; - -template class MemoryManager { private: constexpr static size_t MIN_ITEMS_IN_BLOCK = 1024; + public: static std::shared_ptr instance() { @@ -33,9 +30,10 @@ class MemoryManager return instance; } + template T *allocate(std::size_t n) { - size_t free_list_index = get_next_power_of_two_exponent(n); + size_t free_list_index = get_next_power_of_two_exponent(n * sizeof(T)); auto &free_list = free_lists_[free_list_index]; const auto items_in_block = 1u << free_list_index; if (free_list.empty()) @@ -43,32 +41,34 @@ class MemoryManager // Check if there is space in current block if (current_block_left_items_ < items_in_block) { - allocate_block(items_in_block); + allocate_block(items_in_block); } free_list.push_back(current_block_ptr_); current_block_left_items_ -= items_in_block; - current_block_ptr_ += items_in_block; + current_block_ptr_ += items_in_block * sizeof(T); } - auto ptr = free_list.back(); + auto ptr = static_cast(free_list.back()); free_list.pop_back(); return ptr; } + template void deallocate(T *p, std::size_t n) noexcept { - size_t free_list_index = get_next_power_of_two_exponent(n); + size_t free_list_index = get_next_power_of_two_exponent(n * sizeof(T)); free_lists_[free_list_index].push_back(p); } ~MemoryManager() { - // std::cerr << "~MemoryManager()" << std::endl; + std::cerr << "~MemoryManager()" << std::endl; for (auto block : blocks_) { std::free(block); } } + private: MemoryManager() = default; MemoryManager(const MemoryManager &) = delete; @@ -80,25 +80,26 @@ class MemoryManager return (sizeof(size_t) * 8) - std::countl_zero(n - 1); } + template void allocate_block(size_t items_in_block) { items_in_block = std::max(items_in_block, MIN_ITEMS_IN_BLOCK); size_t block_size = items_in_block * sizeof(T); - T *block = static_cast(std::malloc(block_size)); + void *block = std::malloc(block_size); if (!block) { throw std::bad_alloc(); } total_allocated_ += block_size; blocks_.push_back(block); - current_block_ptr_ = block; + current_block_ptr_ = static_cast(block); current_block_left_items_ = items_in_block; } - std::array, 32> free_lists_; - std::vector blocks_; - T *current_block_ptr_ = nullptr; + std::array, 32> free_lists_; + std::vector blocks_; + uint8_t *current_block_ptr_ = nullptr; size_t current_block_left_items_ = 0; size_t total_allocated_ = 0; @@ -110,10 +111,10 @@ class PoolAllocator public: using value_type = T; - PoolAllocator() noexcept : pool(MemoryManager::instance()) {}; + PoolAllocator() noexcept : pool(MemoryManager::instance()) {}; template - PoolAllocator(const PoolAllocator &) noexcept : pool(MemoryManager::instance()) {} + PoolAllocator(const PoolAllocator &) noexcept : pool(MemoryManager::instance()) {} template struct rebind @@ -123,15 +124,17 @@ class PoolAllocator T *allocate(std::size_t n) { - return pool->allocate(n); + return pool->allocate(n); } void deallocate(T *p, std::size_t n) noexcept { - pool->deallocate(p, n); + pool->deallocate(p, n); } - ~PoolAllocator() = default; + ~PoolAllocator() { + std::cerr << "~PoolAllocator()" << std::endl; + } PoolAllocator(const PoolAllocator &) = default; PoolAllocator &operator=(const PoolAllocator &) = default; @@ -139,9 +142,8 @@ class PoolAllocator PoolAllocator &operator=(PoolAllocator &&) noexcept = default; private: - std::shared_ptr> pool; + std::shared_ptr pool; }; - template bool operator==(const PoolAllocator &, const PoolAllocator &) { diff --git a/include/util/query_heap.hpp b/include/util/query_heap.hpp index 44f18355334..367796ce414 100644 --- a/include/util/query_heap.hpp +++ b/include/util/query_heap.hpp @@ -101,6 +101,10 @@ template class UnorderedMapStorage public: explicit UnorderedMapStorage(std::size_t) { nodes.rehash(1000); } + ~UnorderedMapStorage() { + std::cerr << "~UnorderedMapStorage()" << std::endl; + } + Key &operator[](const NodeID node) { return nodes[node]; } Key peek_index(const NodeID node) const @@ -124,7 +128,7 @@ template class UnorderedMapStorage private: template using UnorderedMap = std:: - unordered_map, std::equal_to, PoolAllocator>*/>; + unordered_map, std::equal_to, PoolAllocator>>; UnorderedMap nodes; }; From 21f53ed6dd670238a6cf14af0bc1be8b29795364 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 11 Jul 2024 23:22:45 +0200 Subject: [PATCH 38/47] Use pool in std::unordered_map --- include/util/pool_allocator.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index 9015d111e5d..1f2b6510db4 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -30,6 +30,7 @@ class MemoryManager return instance; } + // TODO: alignment!!! template T *allocate(std::size_t n) { From f18791a71b62d90b04da3de45e25ce6697962fb8 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Fri, 12 Jul 2024 18:39:32 +0200 Subject: [PATCH 39/47] wip --- src/engine/search_engine_data.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/engine/search_engine_data.cpp b/src/engine/search_engine_data.cpp index be9e731d53c..e749db6c465 100644 --- a/src/engine/search_engine_data.cpp +++ b/src/engine/search_engine_data.cpp @@ -118,15 +118,10 @@ void SearchEngineData::InitializeOrClearManyToManyThreadLocalStorage(unsigne using MLD = routing_algorithms::mld::Algorithm; thread_local SearchEngineData::SearchEngineHeapPtr SearchEngineData::forward_heap_1; thread_local SearchEngineData::SearchEngineHeapPtr SearchEngineData::reverse_heap_1; -<<<<<<< HEAD -thread_local SearchEngineData::MapMatchingHeapPtr SearchEngineData::map_matching_forward_heap_1; -thread_local SearchEngineData::MapMatchingHeapPtr SearchEngineData::map_matching_reverse_heap_1; -======= thread_local SearchEngineData::MapMatchingHeapPtr SearchEngineData::map_matching_forward_heap_1; thread_local SearchEngineData::MapMatchingHeapPtr SearchEngineData::map_matching_reverse_heap_1; ->>>>>>> master thread_local SearchEngineData::ManyToManyHeapPtr SearchEngineData::many_to_many_heap; void SearchEngineData::InitializeOrClearMapMatchingThreadLocalStorage( From 81d128b100564da4f7bc5f0524b1f35d88c01ce0 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Fri, 12 Jul 2024 19:57:23 +0200 Subject: [PATCH 40/47] wip --- include/customizer/cell_customizer.hpp | 1 - include/util/pool_allocator.hpp | 94 ++++++++++++++------------ include/util/query_heap.hpp | 4 -- src/util/pool_allocator.cpp | 5 -- test/data/Makefile | 2 +- unit_tests/util/pool_allocator.cpp | 29 ++++++++ 6 files changed, 79 insertions(+), 56 deletions(-) delete mode 100644 src/util/pool_allocator.cpp diff --git a/include/customizer/cell_customizer.hpp b/include/customizer/cell_customizer.hpp index d92bd411e3b..53570c51d1d 100644 --- a/include/customizer/cell_customizer.hpp +++ b/include/customizer/cell_customizer.hpp @@ -116,7 +116,6 @@ class CellCustomizer const std::vector &allowed_nodes, CellMetric &metric) const { - // std::cerr << "Customizing cells\n"; const auto number_of_nodes = graph.GetNumberOfNodes(); HeapPtr heaps([number_of_nodes]{ return Heap{number_of_nodes}; diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index 1f2b6510db4..76bd272028f 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -14,40 +15,42 @@ namespace osrm::util { -class MemoryManager +class MemoryPool { private: - constexpr static size_t MIN_ITEMS_IN_BLOCK = 1024; + constexpr static size_t MIN_CHUNK_SIZE_BYTES = 4096; public: - static std::shared_ptr instance() + static std::shared_ptr instance() { - static thread_local std::shared_ptr instance; + static thread_local std::shared_ptr instance; if (!instance) { - instance = std::shared_ptr(new MemoryManager()); + instance = std::shared_ptr(new MemoryPool()); } return instance; } - // TODO: alignment!!! template - T *allocate(std::size_t n) + T *allocate(std::size_t items_count) { - size_t free_list_index = get_next_power_of_two_exponent(n * sizeof(T)); + static_assert(alignof(T) <= alignof(std::max_align_t), "Type is over-aligned for this allocator."); + + size_t free_list_index = get_next_power_of_two_exponent(items_count * sizeof(T)); auto &free_list = free_lists_[free_list_index]; - const auto items_in_block = 1u << free_list_index; if (free_list.empty()) { - // Check if there is space in current block - if (current_block_left_items_ < items_in_block) + size_t block_size_in_bytes = 1u << free_list_index; + block_size_in_bytes = align_up(block_size_in_bytes, alignof(std::max_align_t)); + // Check if there is space in current memory chunk + if (current_chunk_left_bytes_ < block_size_in_bytes) { - allocate_block(items_in_block); + allocate_chunk(block_size_in_bytes); } - free_list.push_back(current_block_ptr_); - current_block_left_items_ -= items_in_block; - current_block_ptr_ += items_in_block * sizeof(T); + free_list.push_back(current_chunk_ptr_); + current_chunk_left_bytes_ -= block_size_in_bytes; + current_chunk_ptr_ += block_size_in_bytes; } auto ptr = static_cast(free_list.back()); free_list.pop_back(); @@ -61,49 +64,54 @@ class MemoryManager free_lists_[free_list_index].push_back(p); } - ~MemoryManager() + ~MemoryPool() { - std::cerr << "~MemoryManager()" << std::endl; - for (auto block : blocks_) + for (auto chunk : chunks_) { - std::free(block); + // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) + std::free(chunk); } } private: - MemoryManager() = default; - MemoryManager(const MemoryManager &) = delete; - MemoryManager &operator=(const MemoryManager &) = delete; + MemoryPool() = default; + MemoryPool(const MemoryPool &) = delete; + MemoryPool &operator=(const MemoryPool &) = delete; - size_t get_next_power_of_two_exponent(size_t n) const + inline size_t get_next_power_of_two_exponent(size_t n) const { BOOST_ASSERT(n > 0); return (sizeof(size_t) * 8) - std::countl_zero(n - 1); } - template - void allocate_block(size_t items_in_block) + inline size_t align_up(size_t n, size_t alignment) + { + return (n + alignment - 1) & ~(alignment - 1); + } + + inline void* align_pointer(void* ptr, size_t alignment) { - items_in_block = std::max(items_in_block, MIN_ITEMS_IN_BLOCK); + return reinterpret_cast(align_up(reinterpret_cast(ptr), alignment)); + } - size_t block_size = items_in_block * sizeof(T); - void *block = std::malloc(block_size); - if (!block) + void allocate_chunk(size_t bytes) + { + auto chunk_size = std::max(bytes, MIN_CHUNK_SIZE_BYTES); + // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) + void *chunk = std::malloc(chunk_size); + if (!chunk) { throw std::bad_alloc(); } - total_allocated_ += block_size; - blocks_.push_back(block); - current_block_ptr_ = static_cast(block); - current_block_left_items_ = items_in_block; + chunks_.push_back(chunk); + current_chunk_ptr_ = static_cast(chunk); + current_chunk_left_bytes_ = chunk_size; } std::array, 32> free_lists_; - std::vector blocks_; - uint8_t *current_block_ptr_ = nullptr; - size_t current_block_left_items_ = 0; - - size_t total_allocated_ = 0; + std::vector chunks_; + uint8_t *current_chunk_ptr_ = nullptr; + size_t current_chunk_left_bytes_ = 0; }; template @@ -112,10 +120,10 @@ class PoolAllocator public: using value_type = T; - PoolAllocator() noexcept : pool(MemoryManager::instance()) {}; + PoolAllocator() noexcept : pool(MemoryPool::instance()) {}; template - PoolAllocator(const PoolAllocator &) noexcept : pool(MemoryManager::instance()) {} + PoolAllocator(const PoolAllocator &) noexcept : pool(MemoryPool::instance()) {} template struct rebind @@ -133,17 +141,13 @@ class PoolAllocator pool->deallocate(p, n); } - ~PoolAllocator() { - std::cerr << "~PoolAllocator()" << std::endl; - } - PoolAllocator(const PoolAllocator &) = default; PoolAllocator &operator=(const PoolAllocator &) = default; PoolAllocator(PoolAllocator &&) noexcept = default; PoolAllocator &operator=(PoolAllocator &&) noexcept = default; private: - std::shared_ptr pool; + std::shared_ptr pool; }; template bool operator==(const PoolAllocator &, const PoolAllocator &) diff --git a/include/util/query_heap.hpp b/include/util/query_heap.hpp index fc71f208b4b..42818cb7f4d 100644 --- a/include/util/query_heap.hpp +++ b/include/util/query_heap.hpp @@ -36,10 +36,6 @@ template class UnorderedMapStorage public: explicit UnorderedMapStorage(std::size_t) { nodes.rehash(1000); } - ~UnorderedMapStorage() { - std::cerr << "~UnorderedMapStorage()" << std::endl; - } - Key &operator[](const NodeID node) { return nodes[node]; } Key peek_index(const NodeID node) const diff --git a/src/util/pool_allocator.cpp b/src/util/pool_allocator.cpp deleted file mode 100644 index 4b55e524cf9..00000000000 --- a/src/util/pool_allocator.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "util/pool_allocator.hpp" - -namespace osrm::util -{ -} // namespace osrm::util \ No newline at end of file diff --git a/test/data/Makefile b/test/data/Makefile index b79e87fe0e2..2c617405b9a 100755 --- a/test/data/Makefile +++ b/test/data/Makefile @@ -65,4 +65,4 @@ benchmark: data $(DATA_NAME).requests checksum: $(MD5SUM) $(DATA_NAME).osm.pbf $(DATA_NAME).poly > data.md5sum -.PHONY: clean checksum benchmark data \ No newline at end of file +.PHONY: clean checksum benchmark data diff --git a/unit_tests/util/pool_allocator.cpp b/unit_tests/util/pool_allocator.cpp index 215cdebd5c1..de013f78823 100644 --- a/unit_tests/util/pool_allocator.cpp +++ b/unit_tests/util/pool_allocator.cpp @@ -85,4 +85,33 @@ BOOST_AUTO_TEST_CASE(unordered_map) BOOST_CHECK_EQUAL(map[2], 43); } +BOOST_AUTO_TEST_CASE(alignment) +{ + PoolAllocator pool_char; + PoolAllocator pool_double; + + auto ptr_char = pool_char.allocate(1); + auto ptr_double = pool_double.allocate(1); + + BOOST_CHECK_NE(ptr_double, nullptr); + BOOST_CHECK_EQUAL(reinterpret_cast(ptr_double) % alignof(double), 0); + BOOST_CHECK_NE(ptr_char, nullptr); + BOOST_CHECK_EQUAL(reinterpret_cast(ptr_char) % alignof(char), 0); + + pool_char.deallocate(ptr_char, 1); + pool_double.deallocate(ptr_double, 1); + + + ptr_char = pool_char.allocate(2); + ptr_double = pool_double.allocate(1); + + BOOST_CHECK_NE(ptr_double, nullptr); + BOOST_CHECK_EQUAL(reinterpret_cast(ptr_double) % alignof(double), 0); + BOOST_CHECK_NE(ptr_char, nullptr); + BOOST_CHECK_EQUAL(reinterpret_cast(ptr_char) % alignof(char), 0); + + pool_char.deallocate(ptr_char, 2); + pool_double.deallocate(ptr_double, 1); +} + BOOST_AUTO_TEST_SUITE_END() From fdd1ca05df759f86970d2dd2211a11b794962b4b Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Fri, 12 Jul 2024 20:13:40 +0200 Subject: [PATCH 41/47] wip --- include/customizer/cell_customizer.hpp | 4 +- include/util/pool_allocator.hpp | 83 ++++++++++++-------------- include/util/query_heap.hpp | 6 +- src/benchmarks/bench.cpp | 5 +- unit_tests/util/pool_allocator.cpp | 57 +++++++++++++++--- 5 files changed, 92 insertions(+), 63 deletions(-) diff --git a/include/customizer/cell_customizer.hpp b/include/customizer/cell_customizer.hpp index 53570c51d1d..0fd6dcbc101 100644 --- a/include/customizer/cell_customizer.hpp +++ b/include/customizer/cell_customizer.hpp @@ -117,9 +117,7 @@ class CellCustomizer CellMetric &metric) const { const auto number_of_nodes = graph.GetNumberOfNodes(); - HeapPtr heaps([number_of_nodes]{ - return Heap{number_of_nodes}; - }); + HeapPtr heaps([number_of_nodes] { return Heap{number_of_nodes}; }); for (std::size_t level = 1; level < partition.GetNumberOfLevels(); ++level) { diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index 76bd272028f..edd658f2b7f 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -6,21 +6,31 @@ #include #include #include -#include +#include #include #include #include -#include namespace osrm::util { +inline size_t align_up(size_t n, size_t alignment) +{ + return (n + alignment - 1) & ~(alignment - 1); +} + +inline size_t get_next_power_of_two_exponent(size_t n) +{ + BOOST_ASSERT(n > 0); + return (sizeof(size_t) * 8) - std::countl_zero(n - 1); +} + class MemoryPool { -private: + private: constexpr static size_t MIN_CHUNK_SIZE_BYTES = 4096; -public: + public: static std::shared_ptr instance() { static thread_local std::shared_ptr instance; @@ -31,10 +41,10 @@ class MemoryPool return instance; } - template - T *allocate(std::size_t items_count) + template T *allocate(std::size_t items_count) { - static_assert(alignof(T) <= alignof(std::max_align_t), "Type is over-aligned for this allocator."); + static_assert(alignof(T) <= alignof(std::max_align_t), + "Type is over-aligned for this allocator."); size_t free_list_index = get_next_power_of_two_exponent(items_count * sizeof(T)); auto &free_list = free_lists_[free_list_index]; @@ -42,7 +52,7 @@ class MemoryPool { size_t block_size_in_bytes = 1u << free_list_index; block_size_in_bytes = align_up(block_size_in_bytes, alignof(std::max_align_t)); - // Check if there is space in current memory chunk + // check if there is space in current memory chunk if (current_chunk_left_bytes_ < block_size_in_bytes) { allocate_chunk(block_size_in_bytes); @@ -52,13 +62,12 @@ class MemoryPool current_chunk_left_bytes_ -= block_size_in_bytes; current_chunk_ptr_ += block_size_in_bytes; } - auto ptr = static_cast(free_list.back()); + auto ptr = static_cast(free_list.back()); free_list.pop_back(); return ptr; } - template - void deallocate(T *p, std::size_t n) noexcept + template void deallocate(T *p, std::size_t n) noexcept { size_t free_list_index = get_next_power_of_two_exponent(n * sizeof(T)); free_lists_[free_list_index].push_back(p); @@ -73,27 +82,11 @@ class MemoryPool } } -private: + private: MemoryPool() = default; MemoryPool(const MemoryPool &) = delete; MemoryPool &operator=(const MemoryPool &) = delete; - inline size_t get_next_power_of_two_exponent(size_t n) const - { - BOOST_ASSERT(n > 0); - return (sizeof(size_t) * 8) - std::countl_zero(n - 1); - } - - inline size_t align_up(size_t n, size_t alignment) - { - return (n + alignment - 1) & ~(alignment - 1); - } - - inline void* align_pointer(void* ptr, size_t alignment) - { - return reinterpret_cast(align_up(reinterpret_cast(ptr), alignment)); - } - void allocate_chunk(size_t bytes) { auto chunk_size = std::max(bytes, MIN_CHUNK_SIZE_BYTES); @@ -104,49 +97,47 @@ class MemoryPool throw std::bad_alloc(); } chunks_.push_back(chunk); - current_chunk_ptr_ = static_cast(chunk); + current_chunk_ptr_ = static_cast(chunk); current_chunk_left_bytes_ = chunk_size; } - std::array, 32> free_lists_; + // we have 64 free lists, one for each possible power of two + std::array, sizeof(std::size_t) * 8> free_lists_; + + // list of allocated memory chunks, we don't free them until the pool is destroyed std::vector chunks_; + uint8_t *current_chunk_ptr_ = nullptr; size_t current_chunk_left_bytes_ = 0; }; -template -class PoolAllocator +template class PoolAllocator { -public: + public: using value_type = T; - PoolAllocator() noexcept : pool(MemoryPool::instance()) {}; + PoolAllocator() noexcept : pool(MemoryPool::instance()){}; template - PoolAllocator(const PoolAllocator &) noexcept : pool(MemoryPool::instance()) {} + PoolAllocator(const PoolAllocator &) noexcept : pool(MemoryPool::instance()) + { + } - template - struct rebind + template struct rebind { using other = PoolAllocator; }; - T *allocate(std::size_t n) - { - return pool->allocate(n); - } + T *allocate(std::size_t n) { return pool->allocate(n); } - void deallocate(T *p, std::size_t n) noexcept - { - pool->deallocate(p, n); - } + void deallocate(T *p, std::size_t n) noexcept { pool->deallocate(p, n); } PoolAllocator(const PoolAllocator &) = default; PoolAllocator &operator=(const PoolAllocator &) = default; PoolAllocator(PoolAllocator &&) noexcept = default; PoolAllocator &operator=(PoolAllocator &&) noexcept = default; -private: + private: std::shared_ptr pool; }; template diff --git a/include/util/query_heap.hpp b/include/util/query_heap.hpp index 42818cb7f4d..c12a7d38821 100644 --- a/include/util/query_heap.hpp +++ b/include/util/query_heap.hpp @@ -148,8 +148,6 @@ class QueryHeap } }; - - using HeapContainer = boost::heap::d_ary_heap, boost::heap::mutable_, @@ -169,8 +167,8 @@ class QueryHeap Data data; }; - QueryHeap(const QueryHeap& other) = delete; - QueryHeap(QueryHeap&& other) = delete; + QueryHeap(const QueryHeap &other) = delete; + QueryHeap(QueryHeap &&other) = delete; template explicit QueryHeap(StorageArgs... args) : node_index(args...) { diff --git a/src/benchmarks/bench.cpp b/src/benchmarks/bench.cpp index 45ef1d8faae..d11277db382 100644 --- a/src/benchmarks/bench.cpp +++ b/src/benchmarks/bench.cpp @@ -12,9 +12,9 @@ #include "osrm/coordinate.hpp" #include "osrm/engine_config.hpp" #include "osrm/json_container.hpp" -#include "util/meminfo.hpp" #include "osrm/osrm.hpp" #include "osrm/status.hpp" +#include "util/meminfo.hpp" #include @@ -656,7 +656,8 @@ try return EXIT_FAILURE; } - std::cout << "Peak RAM: " << osrm::util::PeakRAMUsedInBytes() / (1024 * 1024) << "MB" << std::endl; + std::cout << "Peak RAM: " << osrm::util::PeakRAMUsedInBytes() / (1024 * 1024) << "MB" + << std::endl; return EXIT_SUCCESS; } catch (const std::exception &e) diff --git a/unit_tests/util/pool_allocator.cpp b/unit_tests/util/pool_allocator.cpp index de013f78823..7f88dfb858d 100644 --- a/unit_tests/util/pool_allocator.cpp +++ b/unit_tests/util/pool_allocator.cpp @@ -9,7 +9,44 @@ BOOST_AUTO_TEST_SUITE(pool_allocator) using namespace osrm; using namespace osrm::util; -// in many of these tests we hope on address sanitizer to alert in the case if we are doing something wrong +BOOST_AUTO_TEST_CASE(test_align_up) +{ + BOOST_CHECK_EQUAL(align_up(5, 4), 8); + BOOST_CHECK_EQUAL(align_up(9, 8), 16); + BOOST_CHECK_EQUAL(align_up(17, 16), 32); + BOOST_CHECK_EQUAL(align_up(4, 4), 4); + BOOST_CHECK_EQUAL(align_up(8, 8), 8); + BOOST_CHECK_EQUAL(align_up(16, 16), 16); + BOOST_CHECK_EQUAL(align_up(32, 16), 32); + BOOST_CHECK_EQUAL(align_up(0, 4), 0); + BOOST_CHECK_EQUAL(align_up(0, 8), 0); + BOOST_CHECK_EQUAL(align_up(0, 16), 0); + BOOST_CHECK_EQUAL(align_up(1000000, 256), 1000192); + BOOST_CHECK_EQUAL(align_up(999999, 512), 1000448); + BOOST_CHECK_EQUAL(align_up(123456789, 1024), 123457536); + BOOST_CHECK_EQUAL(align_up(0, 1), 0); + BOOST_CHECK_EQUAL(align_up(5, 1), 5); + BOOST_CHECK_EQUAL(align_up(123456, 1), 123456); +} + +BOOST_AUTO_TEST_CASE(test_get_next_power_of_two_exponent) +{ + BOOST_CHECK_EQUAL(get_next_power_of_two_exponent(1), 0); + BOOST_CHECK_EQUAL(get_next_power_of_two_exponent(2), 1); + BOOST_CHECK_EQUAL(get_next_power_of_two_exponent(4), 2); + BOOST_CHECK_EQUAL(get_next_power_of_two_exponent(8), 3); + BOOST_CHECK_EQUAL(get_next_power_of_two_exponent(16), 4); + BOOST_CHECK_EQUAL(get_next_power_of_two_exponent(3), 2); + BOOST_CHECK_EQUAL(get_next_power_of_two_exponent(5), 3); + BOOST_CHECK_EQUAL(get_next_power_of_two_exponent(9), 4); + BOOST_CHECK_EQUAL(get_next_power_of_two_exponent(15), 4); + BOOST_CHECK_EQUAL(get_next_power_of_two_exponent(17), 5); + BOOST_CHECK_EQUAL(get_next_power_of_two_exponent(1), 0); + BOOST_CHECK_EQUAL(get_next_power_of_two_exponent(SIZE_MAX), sizeof(size_t) * 8); +} + +// in many of these tests we hope on address sanitizer to alert in the case if we are doing +// something wrong BOOST_AUTO_TEST_CASE(smoke) { PoolAllocator pool; @@ -74,7 +111,12 @@ BOOST_AUTO_TEST_CASE(move) BOOST_AUTO_TEST_CASE(unordered_map) { - std::unordered_map, std::equal_to, PoolAllocator>> map; + std::unordered_map, + std::equal_to, + PoolAllocator>> + map; map[1] = 42; BOOST_CHECK_EQUAL(map[1], 42); @@ -87,9 +129,9 @@ BOOST_AUTO_TEST_CASE(unordered_map) BOOST_AUTO_TEST_CASE(alignment) { - PoolAllocator pool_char; - PoolAllocator pool_double; - + PoolAllocator pool_char; + PoolAllocator pool_double; + auto ptr_char = pool_char.allocate(1); auto ptr_double = pool_double.allocate(1); @@ -98,9 +140,8 @@ BOOST_AUTO_TEST_CASE(alignment) BOOST_CHECK_NE(ptr_char, nullptr); BOOST_CHECK_EQUAL(reinterpret_cast(ptr_char) % alignof(char), 0); - pool_char.deallocate(ptr_char, 1); - pool_double.deallocate(ptr_double, 1); - + pool_char.deallocate(ptr_char, 1); + pool_double.deallocate(ptr_double, 1); ptr_char = pool_char.allocate(2); ptr_double = pool_double.allocate(1); From 70d67d0eeae016eff2787a7b20ce1696b67692f9 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Fri, 12 Jul 2024 20:36:47 +0200 Subject: [PATCH 42/47] wip --- .github/workflows/osrm-backend.yml | 586 ++++++++++++++--------------- 1 file changed, 293 insertions(+), 293 deletions(-) diff --git a/.github/workflows/osrm-backend.yml b/.github/workflows/osrm-backend.yml index 0af12b9e77c..0ebe1860e11 100644 --- a/.github/workflows/osrm-backend.yml +++ b/.github/workflows/osrm-backend.yml @@ -23,159 +23,159 @@ concurrency: cancel-in-progress: true jobs: - # windows-release-node: - # needs: format-taginfo-docs - # runs-on: windows-2022 - # continue-on-error: false - # env: - # BUILD_TYPE: Release - # steps: - # - uses: actions/checkout@v4 - # - run: pip install "conan<2.0.0" - # - run: conan --version - # - run: cmake --version - # - uses: actions/setup-node@v4 - # with: - # node-version: 18 - # - run: node --version - # - run: npm --version - # - name: Prepare environment - # shell: bash - # run: | - # PACKAGE_JSON_VERSION=$(node -e "console.log(require('./package.json').version)") - # echo PUBLISH=$([[ "${GITHUB_REF:-}" == "refs/tags/v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off") >> $GITHUB_ENV - # - run: npm install --ignore-scripts - # - run: npm link --ignore-scripts - # - name: Build - # shell: bash - # run: | - # mkdir build - # cd build - # cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_CONAN=ON -DENABLE_NODE_BINDINGS=ON .. - # cmake --build . --config Release + windows-release-node: + needs: format-taginfo-docs + runs-on: windows-2022 + continue-on-error: false + env: + BUILD_TYPE: Release + steps: + - uses: actions/checkout@v4 + - run: pip install "conan<2.0.0" + - run: conan --version + - run: cmake --version + - uses: actions/setup-node@v4 + with: + node-version: 18 + - run: node --version + - run: npm --version + - name: Prepare environment + shell: bash + run: | + PACKAGE_JSON_VERSION=$(node -e "console.log(require('./package.json').version)") + echo PUBLISH=$([[ "${GITHUB_REF:-}" == "refs/tags/v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off") >> $GITHUB_ENV + - run: npm install --ignore-scripts + - run: npm link --ignore-scripts + - name: Build + shell: bash + run: | + mkdir build + cd build + cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_CONAN=ON -DENABLE_NODE_BINDINGS=ON .. + cmake --build . --config Release - # # TODO: MSVC goes out of memory when building our tests - # # - name: Run tests - # # shell: bash - # # run: | - # # cd build - # # cmake --build . --config Release --target tests - # # # TODO: run tests - # # - name: Run node tests - # # shell: bash - # # run: | - # # ./lib/binding/osrm-extract.exe -p profiles/car.lua test/data/monaco.osm.pbf - - # # mkdir -p test/data/ch - # # cp test/data/monaco.osrm* test/data/ch/ - # # ./lib/binding/osrm-contract.exe test/data/ch/monaco.osrm - - # # ./lib/binding/osrm-datastore.exe test/data/ch/monaco.osrm - # # node test/nodejs/index.js - # - name: Build Node package - # shell: bash - # run: ./scripts/ci/node_package.sh - # - name: Publish Node package - # if: ${{ env.PUBLISH == 'On' }} - # uses: ncipollo/release-action@v1 - # with: - # allowUpdates: true - # artifactErrorsFailBuild: true - # artifacts: build/stage/**/*.tar.gz - # omitBody: true - # omitBodyDuringUpdate: true - # omitName: true - # omitNameDuringUpdate: true - # replacesArtifacts: true - # token: ${{ secrets.GITHUB_TOKEN }} - - # format-taginfo-docs: - # runs-on: ubuntu-22.04 - # steps: - # - uses: actions/checkout@v4 - # - name: Use Node.js - # uses: actions/setup-node@v4 - # with: - # node-version: 18 - # - name: Enable Node.js cache - # uses: actions/cache@v4 - # with: - # path: ~/.npm - # key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} - # restore-keys: | - # ${{ runner.os }}-node- - # - name: Prepare environment - # run: | - # npm ci --ignore-scripts - # clang-format-15 --version - # - name: Run checks - # run: | - # ./scripts/check_taginfo.py taginfo.json profiles/car.lua - # ./scripts/format.sh && ./scripts/error_on_dirty.sh - # node ./scripts/validate_changelog.js - # npm run docs && ./scripts/error_on_dirty.sh - # npm audit --production - - # docker-image-matrix: - # strategy: - # matrix: - # docker-base-image: ["debian", "alpine"] - # needs: format-taginfo-docs - # runs-on: ubuntu-22.04 - # continue-on-error: false - # steps: - # - name: Check out the repo - # uses: actions/checkout@v4 - # - name: Enable osm.pbf cache - # uses: actions/cache@v4 - # with: - # path: berlin-latest.osm.pbf - # key: v1-berlin-osm-pbf - # restore-keys: | - # v1-berlin-osm-pbf - # - name: Docker build - # run: | - # docker build -t osrm-backend-local -f docker/Dockerfile-${{ matrix.docker-base-image }} . - # - name: Test Docker image - # run: | - # if [ ! -f "${PWD}/berlin-latest.osm.pbf" ]; then - # wget http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf - # fi - # TAG=osrm-backend-local - # # when `--memory-swap` value equals `--memory` it means container won't use swap - # # see https://docs.docker.com/config/containers/resource_constraints/#--memory-swap-details - # MEMORY_ARGS="--memory=1g --memory-swap=1g" - # docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-extract --dump-nbg-graph -p /opt/car.lua /data/berlin-latest.osm.pbf - # docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-components /data/berlin-latest.osrm.nbg /data/berlin-latest.geojson - # if [ ! -s "${PWD}/berlin-latest.geojson" ] - # then - # >&2 echo "No berlin-latest.geojson found" - # exit 1 - # fi - # # removing `.osrm.nbg` to check that whole pipeline works without it - # rm -rf "${PWD}/berlin-latest.osrm.nbg" - - # docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-partition /data/berlin-latest.osrm - # docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-customize /data/berlin-latest.osrm - # docker run $MEMORY_ARGS --name=osrm-container -t -p 5000:5000 -v "${PWD}:/data" "${TAG}" osrm-routed --algorithm mld /data/berlin-latest.osrm & - # curl --retry-delay 3 --retry 10 --retry-all-errors "http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true" - # docker stop osrm-container + # TODO: MSVC goes out of memory when building our tests + # - name: Run tests + # shell: bash + # run: | + # cd build + # cmake --build . --config Release --target tests + # # TODO: run tests + # - name: Run node tests + # shell: bash + # run: | + # ./lib/binding/osrm-extract.exe -p profiles/car.lua test/data/monaco.osm.pbf + + # mkdir -p test/data/ch + # cp test/data/monaco.osrm* test/data/ch/ + # ./lib/binding/osrm-contract.exe test/data/ch/monaco.osrm + + # ./lib/binding/osrm-datastore.exe test/data/ch/monaco.osrm + # node test/nodejs/index.js + - name: Build Node package + shell: bash + run: ./scripts/ci/node_package.sh + - name: Publish Node package + if: ${{ env.PUBLISH == 'On' }} + uses: ncipollo/release-action@v1 + with: + allowUpdates: true + artifactErrorsFailBuild: true + artifacts: build/stage/**/*.tar.gz + omitBody: true + omitBodyDuringUpdate: true + omitName: true + omitNameDuringUpdate: true + replacesArtifacts: true + token: ${{ secrets.GITHUB_TOKEN }} + + format-taginfo-docs: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: 18 + - name: Enable Node.js cache + uses: actions/cache@v4 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + - name: Prepare environment + run: | + npm ci --ignore-scripts + clang-format-15 --version + - name: Run checks + run: | + ./scripts/check_taginfo.py taginfo.json profiles/car.lua + ./scripts/format.sh && ./scripts/error_on_dirty.sh + node ./scripts/validate_changelog.js + npm run docs && ./scripts/error_on_dirty.sh + npm audit --production + + docker-image-matrix: + strategy: + matrix: + docker-base-image: ["debian", "alpine"] + needs: format-taginfo-docs + runs-on: ubuntu-22.04 + continue-on-error: false + steps: + - name: Check out the repo + uses: actions/checkout@v4 + - name: Enable osm.pbf cache + uses: actions/cache@v4 + with: + path: berlin-latest.osm.pbf + key: v1-berlin-osm-pbf + restore-keys: | + v1-berlin-osm-pbf + - name: Docker build + run: | + docker build -t osrm-backend-local -f docker/Dockerfile-${{ matrix.docker-base-image }} . + - name: Test Docker image + run: | + if [ ! -f "${PWD}/berlin-latest.osm.pbf" ]; then + wget http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf + fi + TAG=osrm-backend-local + # when `--memory-swap` value equals `--memory` it means container won't use swap + # see https://docs.docker.com/config/containers/resource_constraints/#--memory-swap-details + MEMORY_ARGS="--memory=1g --memory-swap=1g" + docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-extract --dump-nbg-graph -p /opt/car.lua /data/berlin-latest.osm.pbf + docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-components /data/berlin-latest.osrm.nbg /data/berlin-latest.geojson + if [ ! -s "${PWD}/berlin-latest.geojson" ] + then + >&2 echo "No berlin-latest.geojson found" + exit 1 + fi + # removing `.osrm.nbg` to check that whole pipeline works without it + rm -rf "${PWD}/berlin-latest.osrm.nbg" + + docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-partition /data/berlin-latest.osrm + docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-customize /data/berlin-latest.osrm + docker run $MEMORY_ARGS --name=osrm-container -t -p 5000:5000 -v "${PWD}:/data" "${TAG}" osrm-routed --algorithm mld /data/berlin-latest.osrm & + curl --retry-delay 3 --retry 10 --retry-all-errors "http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true" + docker stop osrm-container build-test-publish: - #needs: format-taginfo-docs + needs: format-taginfo-docs strategy: matrix: include: - # - name: gcc-13-debug-cov - # continue-on-error: false - # node: 20 - # runs-on: ubuntu-24.04 - # BUILD_TOOLS: ON - # BUILD_TYPE: Debug - # CCOMPILER: gcc-13 - # CUCUMBER_TIMEOUT: 20000 - # CXXCOMPILER: g++-13 - # ENABLE_COVERAGE: ON + - name: gcc-13-debug-cov + continue-on-error: false + node: 20 + runs-on: ubuntu-24.04 + BUILD_TOOLS: ON + BUILD_TYPE: Debug + CCOMPILER: gcc-13 + CUCUMBER_TIMEOUT: 20000 + CXXCOMPILER: g++-13 + ENABLE_COVERAGE: ON - name: clang-18-debug-asan-ubsan continue-on-error: false @@ -191,61 +191,61 @@ jobs: OSRM_CONNECTION_RETRIES: 10 OSRM_CONNECTION_EXP_BACKOFF_COEF: 1.5 - # - name: clang-18-release - # continue-on-error: false - # node: 18 - # runs-on: ubuntu-24.04 - # BUILD_TOOLS: ON - # BUILD_TYPE: Release - # CCOMPILER: clang-18 - # CXXCOMPILER: clang++-18 - # CUCUMBER_TIMEOUT: 60000 - # ENABLE_LTO: OFF - - # - name: clang-18-debug - # continue-on-error: false - # node: 18 - # runs-on: ubuntu-24.04 - # BUILD_TOOLS: ON - # BUILD_TYPE: Debug - # CCOMPILER: clang-18 - # CXXCOMPILER: clang++-18 - # CUCUMBER_TIMEOUT: 60000 - # ENABLE_LTO: OFF - - # - name: clang-18-debug-clang-tidy - # continue-on-error: false - # node: 18 - # runs-on: ubuntu-24.04 - # BUILD_TOOLS: ON - # BUILD_TYPE: Debug - # CCOMPILER: clang-18 - # CXXCOMPILER: clang++-18 - # CUCUMBER_TIMEOUT: 60000 - # ENABLE_CLANG_TIDY: ON - - - # - name: clang-17-release - # continue-on-error: false - # node: 18 - # runs-on: ubuntu-24.04 - # BUILD_TOOLS: ON - # BUILD_TYPE: Release - # CCOMPILER: clang-17 - # CXXCOMPILER: clang++-17 - # CUCUMBER_TIMEOUT: 60000 - # ENABLE_LTO: OFF - - # - name: clang-16-release - # continue-on-error: false - # node: 18 - # runs-on: ubuntu-24.04 - # BUILD_TOOLS: ON - # BUILD_TYPE: Release - # CCOMPILER: clang-16 - # CXXCOMPILER: clang++-16 - # CUCUMBER_TIMEOUT: 60000 - # ENABLE_LTO: OFF + - name: clang-18-release + continue-on-error: false + node: 18 + runs-on: ubuntu-24.04 + BUILD_TOOLS: ON + BUILD_TYPE: Release + CCOMPILER: clang-18 + CXXCOMPILER: clang++-18 + CUCUMBER_TIMEOUT: 60000 + ENABLE_LTO: OFF + + - name: clang-18-debug + continue-on-error: false + node: 18 + runs-on: ubuntu-24.04 + BUILD_TOOLS: ON + BUILD_TYPE: Debug + CCOMPILER: clang-18 + CXXCOMPILER: clang++-18 + CUCUMBER_TIMEOUT: 60000 + ENABLE_LTO: OFF + + - name: clang-18-debug-clang-tidy + continue-on-error: false + node: 18 + runs-on: ubuntu-24.04 + BUILD_TOOLS: ON + BUILD_TYPE: Debug + CCOMPILER: clang-18 + CXXCOMPILER: clang++-18 + CUCUMBER_TIMEOUT: 60000 + ENABLE_CLANG_TIDY: ON + + + - name: clang-17-release + continue-on-error: false + node: 18 + runs-on: ubuntu-24.04 + BUILD_TOOLS: ON + BUILD_TYPE: Release + CCOMPILER: clang-17 + CXXCOMPILER: clang++-17 + CUCUMBER_TIMEOUT: 60000 + ENABLE_LTO: OFF + + - name: clang-16-release + continue-on-error: false + node: 18 + runs-on: ubuntu-24.04 + BUILD_TOOLS: ON + BUILD_TYPE: Release + CCOMPILER: clang-16 + CXXCOMPILER: clang++-16 + CUCUMBER_TIMEOUT: 60000 + ENABLE_LTO: OFF - name: conan-linux-debug-asan-ubsan continue-on-error: false @@ -259,92 +259,92 @@ jobs: ENABLE_SANITIZER: ON ENABLE_LTO: OFF - # - name: conan-linux-release - # continue-on-error: false - # node: 18 - # runs-on: ubuntu-24.04 - # BUILD_TOOLS: ON - # BUILD_TYPE: Release - # CCOMPILER: clang-18 - # CXXCOMPILER: clang++-18 - # ENABLE_CONAN: ON - # ENABLE_LTO: OFF - - # - name: gcc-14-release - # continue-on-error: false - # node: 20 - # runs-on: ubuntu-24.04 - # BUILD_TOOLS: ON - # BUILD_TYPE: Release - # CCOMPILER: gcc-14 - # CXXCOMPILER: g++-14 - # CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized' - - # - name: gcc-13-release - # continue-on-error: false - # node: 20 - # runs-on: ubuntu-24.04 - # BUILD_TOOLS: ON - # BUILD_TYPE: Release - # CCOMPILER: gcc-13 - # CXXCOMPILER: g++-13 - # CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized' - - # - name: gcc-12-release - # continue-on-error: false - # node: 20 - # runs-on: ubuntu-22.04 - # BUILD_TOOLS: ON - # BUILD_TYPE: Release - # CCOMPILER: gcc-12 - # CXXCOMPILER: g++-12 - # CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized' - - # - name: conan-linux-release-node - # build_node_package: true - # continue-on-error: false - # node: 20 - # runs-on: ubuntu-24.04 - # BUILD_TYPE: Release - # CCOMPILER: clang-16 - # CXXCOMPILER: clang++-16 - # ENABLE_CONAN: ON - # NODE_PACKAGE_TESTS_ONLY: ON - - # - name: conan-linux-debug-node - # build_node_package: true - # continue-on-error: false - # node: 20 - # runs-on: ubuntu-24.04 - # BUILD_TYPE: Debug - # CCOMPILER: clang-16 - # CXXCOMPILER: clang++-16 - # ENABLE_CONAN: ON - # NODE_PACKAGE_TESTS_ONLY: ON - - # - name: conan-macos-x64-release-node - # build_node_package: true - # continue-on-error: true - # node: 20 - # runs-on: macos-13 # x86_64 - # BUILD_TYPE: Release - # CCOMPILER: clang - # CXXCOMPILER: clang++ - # CUCUMBER_TIMEOUT: 60000 - # ENABLE_ASSERTIONS: ON - # ENABLE_CONAN: ON - - # - name: conan-macos-arm64-release-node - # build_node_package: true - # continue-on-error: true - # node: 20 - # runs-on: macos-14 # arm64 - # BUILD_TYPE: Release - # CCOMPILER: clang - # CXXCOMPILER: clang++ - # CUCUMBER_TIMEOUT: 60000 - # ENABLE_ASSERTIONS: ON - # ENABLE_CONAN: ON + - name: conan-linux-release + continue-on-error: false + node: 18 + runs-on: ubuntu-24.04 + BUILD_TOOLS: ON + BUILD_TYPE: Release + CCOMPILER: clang-18 + CXXCOMPILER: clang++-18 + ENABLE_CONAN: ON + ENABLE_LTO: OFF + + - name: gcc-14-release + continue-on-error: false + node: 20 + runs-on: ubuntu-24.04 + BUILD_TOOLS: ON + BUILD_TYPE: Release + CCOMPILER: gcc-14 + CXXCOMPILER: g++-14 + CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized' + + - name: gcc-13-release + continue-on-error: false + node: 20 + runs-on: ubuntu-24.04 + BUILD_TOOLS: ON + BUILD_TYPE: Release + CCOMPILER: gcc-13 + CXXCOMPILER: g++-13 + CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized' + + - name: gcc-12-release + continue-on-error: false + node: 20 + runs-on: ubuntu-22.04 + BUILD_TOOLS: ON + BUILD_TYPE: Release + CCOMPILER: gcc-12 + CXXCOMPILER: g++-12 + CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized' + + - name: conan-linux-release-node + build_node_package: true + continue-on-error: false + node: 20 + runs-on: ubuntu-24.04 + BUILD_TYPE: Release + CCOMPILER: clang-16 + CXXCOMPILER: clang++-16 + ENABLE_CONAN: ON + NODE_PACKAGE_TESTS_ONLY: ON + + - name: conan-linux-debug-node + build_node_package: true + continue-on-error: false + node: 20 + runs-on: ubuntu-24.04 + BUILD_TYPE: Debug + CCOMPILER: clang-16 + CXXCOMPILER: clang++-16 + ENABLE_CONAN: ON + NODE_PACKAGE_TESTS_ONLY: ON + + - name: conan-macos-x64-release-node + build_node_package: true + continue-on-error: true + node: 20 + runs-on: macos-13 # x86_64 + BUILD_TYPE: Release + CCOMPILER: clang + CXXCOMPILER: clang++ + CUCUMBER_TIMEOUT: 60000 + ENABLE_ASSERTIONS: ON + ENABLE_CONAN: ON + + - name: conan-macos-arm64-release-node + build_node_package: true + continue-on-error: true + node: 20 + runs-on: macos-14 # arm64 + BUILD_TYPE: Release + CCOMPILER: clang + CXXCOMPILER: clang++ + CUCUMBER_TIMEOUT: 60000 + ENABLE_ASSERTIONS: ON + ENABLE_CONAN: ON name: ${{ matrix.name}} continue-on-error: ${{ matrix.continue-on-error }} @@ -774,9 +774,9 @@ jobs: ccache -p ccache -s - # ci-complete: - # runs-on: ubuntu-22.04 - # needs: [build-test-publish, docker-image-matrix, windows-release-node, benchmarks] - # steps: - # - run: echo "CI complete" + ci-complete: + runs-on: ubuntu-22.04 + needs: [build-test-publish, docker-image-matrix, windows-release-node, benchmarks] + steps: + - run: echo "CI complete" From 8bd26dc8b6b8d6c8e7a2e5ccc44d229b8e2f4f36 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Fri, 12 Jul 2024 20:37:41 +0200 Subject: [PATCH 43/47] wip --- .github/workflows/osrm-backend.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/osrm-backend.yml b/.github/workflows/osrm-backend.yml index 0ebe1860e11..454e273f4ec 100644 --- a/.github/workflows/osrm-backend.yml +++ b/.github/workflows/osrm-backend.yml @@ -652,7 +652,7 @@ jobs: benchmarks: if: github.event_name == 'pull_request' - # needs: [format-taginfo-docs] + needs: [format-taginfo-docs] runs-on: ubuntu-24.04 env: CCOMPILER: clang-16 From 309644050515c7e188ee94ca045afef872f215c0 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Fri, 12 Jul 2024 21:32:52 +0200 Subject: [PATCH 44/47] wip --- include/util/pool_allocator.hpp | 2 +- include/util/query_heap.hpp | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index edd658f2b7f..40cf6a3ea7e 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -70,7 +70,7 @@ class MemoryPool template void deallocate(T *p, std::size_t n) noexcept { size_t free_list_index = get_next_power_of_two_exponent(n * sizeof(T)); - free_lists_[free_list_index].push_back(p); + free_lists_[free_list_index].push_back(static_cast(p)); } ~MemoryPool() diff --git a/include/util/query_heap.hpp b/include/util/query_heap.hpp index c12a7d38821..25633506489 100644 --- a/include/util/query_heap.hpp +++ b/include/util/query_heap.hpp @@ -5,9 +5,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -180,7 +178,6 @@ class QueryHeap heap.clear(); inserted_nodes.clear(); node_index.Clear(); - heap.reserve(1024); } std::size_t Size() const { return heap.size(); } From 6090387c5e9f61566b7c8a7dc739727a708ceb9d Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Fri, 12 Jul 2024 22:10:05 +0200 Subject: [PATCH 45/47] wip --- include/util/meminfo.hpp | 18 ++++-------------- include/util/pool_allocator.hpp | 7 +++++-- src/benchmarks/bench.cpp | 7 ++----- 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/include/util/meminfo.hpp b/include/util/meminfo.hpp index 4c3e16f0b7a..9769b30d4e6 100644 --- a/include/util/meminfo.hpp +++ b/include/util/meminfo.hpp @@ -2,7 +2,6 @@ #define MEMINFO_HPP #include "util/log.hpp" -#include #ifndef _WIN32 #include @@ -11,31 +10,22 @@ namespace osrm::util { -inline size_t PeakRAMUsedInBytes() +inline void DumpMemoryStats() { #ifndef _WIN32 rusage usage; getrusage(RUSAGE_SELF, &usage); #ifdef __linux__ // Under linux, ru.maxrss is in kb - return usage.ru_maxrss * 1024; + util::Log() << "RAM: peak bytes used: " << usage.ru_maxrss * 1024; #else // __linux__ // Under BSD systems (OSX), it's in bytes - return usage.ru_maxrss; + util::Log() << "RAM: peak bytes used: " << usage.ru_maxrss; #endif // __linux__ -#else // _WIN32 - return 0; -#endif // _WIN32 -} - -inline void DumpMemoryStats() -{ -#ifndef _WIN32 - util::Log() << "RAM: peak bytes used: " << PeakRAMUsedInBytes(); #else // _WIN32 util::Log() << "RAM: peak bytes used: "; #endif // _WIN32 } } // namespace osrm::util -#endif +#endif \ No newline at end of file diff --git a/include/util/pool_allocator.hpp b/include/util/pool_allocator.hpp index 40cf6a3ea7e..35ed970756e 100644 --- a/include/util/pool_allocator.hpp +++ b/include/util/pool_allocator.hpp @@ -62,7 +62,7 @@ class MemoryPool current_chunk_left_bytes_ -= block_size_in_bytes; current_chunk_ptr_ += block_size_in_bytes; } - auto ptr = static_cast(free_list.back()); + auto ptr = reinterpret_cast(free_list.back()); free_list.pop_back(); return ptr; } @@ -70,7 +70,8 @@ class MemoryPool template void deallocate(T *p, std::size_t n) noexcept { size_t free_list_index = get_next_power_of_two_exponent(n * sizeof(T)); - free_lists_[free_list_index].push_back(static_cast(p)); + // NOLINTNEXTLINE(bugprone-multi-level-implicit-pointer-conversion) + free_lists_[free_list_index].push_back(reinterpret_cast(p)); } ~MemoryPool() @@ -138,6 +139,8 @@ template class PoolAllocator PoolAllocator &operator=(PoolAllocator &&) noexcept = default; private: + // using shared_ptr guarantees that memory pool won't be destroyed before all allocators using + // it (important if there are static instances of PoolAllocator) std::shared_ptr pool; }; template diff --git a/src/benchmarks/bench.cpp b/src/benchmarks/bench.cpp index d11277db382..23566824b01 100644 --- a/src/benchmarks/bench.cpp +++ b/src/benchmarks/bench.cpp @@ -12,9 +12,9 @@ #include "osrm/coordinate.hpp" #include "osrm/engine_config.hpp" #include "osrm/json_container.hpp" + #include "osrm/osrm.hpp" #include "osrm/status.hpp" -#include "util/meminfo.hpp" #include @@ -655,13 +655,10 @@ try std::cerr << "Unknown benchmark: " << benchmarkToRun << std::endl; return EXIT_FAILURE; } - - std::cout << "Peak RAM: " << osrm::util::PeakRAMUsedInBytes() / (1024 * 1024) << "MB" - << std::endl; return EXIT_SUCCESS; } catch (const std::exception &e) { std::cerr << "Error: " << e.what() << std::endl; return EXIT_FAILURE; -} +} \ No newline at end of file From 9ce059f2166f8e52b9a23df8564bc7bed06b67d7 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Fri, 12 Jul 2024 22:45:56 +0200 Subject: [PATCH 46/47] wip --- include/util/meminfo.hpp | 2 +- src/benchmarks/bench.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/util/meminfo.hpp b/include/util/meminfo.hpp index 9769b30d4e6..e2059975150 100644 --- a/include/util/meminfo.hpp +++ b/include/util/meminfo.hpp @@ -28,4 +28,4 @@ inline void DumpMemoryStats() } } // namespace osrm::util -#endif \ No newline at end of file +#endif diff --git a/src/benchmarks/bench.cpp b/src/benchmarks/bench.cpp index 23566824b01..019ff645659 100644 --- a/src/benchmarks/bench.cpp +++ b/src/benchmarks/bench.cpp @@ -661,4 +661,4 @@ catch (const std::exception &e) { std::cerr << "Error: " << e.what() << std::endl; return EXIT_FAILURE; -} \ No newline at end of file +} From bff349f1b1dc4828b1f0d9af058e5a4c3d4020d3 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Sat, 13 Jul 2024 08:53:15 +0200 Subject: [PATCH 47/47] wip --- .github/workflows/osrm-backend.yml | 79 +++++++++++++----------------- 1 file changed, 34 insertions(+), 45 deletions(-) diff --git a/.github/workflows/osrm-backend.yml b/.github/workflows/osrm-backend.yml index 454e273f4ec..aae7f815e62 100644 --- a/.github/workflows/osrm-backend.yml +++ b/.github/workflows/osrm-backend.yml @@ -653,7 +653,7 @@ jobs: benchmarks: if: github.event_name == 'pull_request' needs: [format-taginfo-docs] - runs-on: ubuntu-24.04 + runs-on: self-hosted env: CCOMPILER: clang-16 CXXCOMPILER: clang++-16 @@ -664,37 +664,17 @@ jobs: GITHUB_REPOSITORY: ${{ github.repository }} RUN_BIG_BENCHMARK: ${{ contains(github.event.pull_request.labels.*.name, 'Performance') }} steps: - - name: Enable data.osm.pbf cache - if: ${{ ! env.RUN_BIG_BENCHMARK }} - uses: actions/cache@v4 - with: - path: ~/data.osm.pbf - key: v1-data-osm-pbf - restore-keys: | - v1-data-osm-pbf - - name: Enable compiler cache - uses: actions/cache@v4 - with: - path: ~/.ccache - key: v1-ccache-benchmarks-${{ github.sha }} - restore-keys: | - v1-ccache-benchmarks- - - name: Enable Conan cache - uses: actions/cache@v4 - with: - path: ~/.conan - key: v1-conan-benchmarks-${{ github.sha }} - restore-keys: | - v1-conan-benchmarks- - name: Checkout PR Branch uses: actions/checkout@v4 with: ref: ${{ github.head_ref }} path: pr - - name: Install dependencies - run: | - python3 -m pip install "conan<2.0.0" "requests==2.31.0" "numpy==1.26.4" --break-system-packages - sudo apt-get update -y && sudo apt-get install ccache + - name: Activate virtualenv + run: | + python3 -m venv .venv + source .venv/bin/activate + echo PATH=$PATH >> $GITHUB_ENV + pip install "conan<2.0.0" "requests==2.31.0" "numpy==1.26.4" - name: Prepare data run: | if [ "$RUN_BIG_BENCHMARK" = "true" ]; then @@ -740,32 +720,41 @@ jobs: make -C test/data # we run benchmarks in tmpfs to avoid impact of disk IO - name: Create folder for tmpfs - run: mkdir -p /opt/benchmarks + run: | + # if by any chance it was mounted before(e.g. due to previous job failed), unmount it + sudo umount ~/benchmarks | true + rm -rf ~/benchmarks + mkdir -p ~/benchmarks + # see https://llvm.org/docs/Benchmarking.html - name: Run PR Benchmarks run: | - sudo mount -t tmpfs -o size=4g none /opt/benchmarks - cp -rf pr/build /opt/benchmarks/build - mkdir -p /opt/benchmarks/test - cp -rf pr/test/data /opt/benchmarks/test/data - cp -rf pr/profiles /opt/benchmarks/profiles - - ./pr/scripts/ci/run_benchmarks.sh -f /opt/benchmarks -r $(pwd)/pr_results -s $(pwd)/pr -b /opt/benchmarks/build -o ~/data.osm.pbf -g ~/gps_traces.csv - sudo umount /opt/benchmarks + sudo cset shield -c 2-3 -k on + sudo mount -t tmpfs -o size=4g none ~/benchmarks + cp -rf pr/build ~/benchmarks/build + mkdir -p ~/benchmarks/test + cp -rf pr/test/data ~/benchmarks/test/data + cp -rf pr/profiles ~/benchmarks/profiles + + sudo cset shield --exec -- ./pr/scripts/ci/run_benchmarks.sh -f ~/benchmarks -r $(pwd)/pr_results -s $(pwd)/pr -b ~/benchmarks/build -o ~/data.osm.pbf -g ~/gps_traces.csv + sudo umount ~/benchmarks + sudo cset shield --reset - name: Run Base Benchmarks run: | - sudo mount -t tmpfs -o size=4g none /opt/benchmarks - cp -rf base/build /opt/benchmarks/build - mkdir -p /opt/benchmarks/test - cp -rf base/test/data /opt/benchmarks/test/data - cp -rf base/profiles /opt/benchmarks/profiles + sudo cset shield -c 2-3 -k on + sudo mount -t tmpfs -o size=4g none ~/benchmarks + cp -rf base/build ~/benchmarks/build + mkdir -p ~/benchmarks/test + cp -rf base/test/data ~/benchmarks/test/data + cp -rf base/profiles ~/benchmarks/profiles # TODO: remove it when base branch will have this file at needed location - if [ ! -f /opt/benchmarks/test/data/portugal_to_korea.json ]; then - cp base/src/benchmarks/portugal_to_korea.json /opt/benchmarks/test/data/portugal_to_korea.json + if [ ! -f ~/benchmarks/test/data/portugal_to_korea.json ]; then + cp base/src/benchmarks/portugal_to_korea.json ~/benchmarks/test/data/portugal_to_korea.json fi # we intentionally use scripts from PR branch to be able to update them and see results in the same PR - ./pr/scripts/ci/run_benchmarks.sh -f /opt/benchmarks -r $(pwd)/base_results -s $(pwd)/pr -b /opt/benchmarks/build -o ~/data.osm.pbf -g ~/gps_traces.csv - sudo umount /opt/benchmarks + sudo cset shield --exec -- cset shield --exec -- ./pr/scripts/ci/run_benchmarks.sh -f ~/benchmarks -r $(pwd)/base_results -s $(pwd)/pr -b ~/benchmarks/build -o ~/data.osm.pbf -g ~/gps_traces.csv + sudo umount ~/benchmarks + sudo cset shield --reset - name: Post Benchmark Results run: | python3 pr/scripts/ci/post_benchmark_results.py base_results pr_results