diff options
-rw-r--r-- | .github/workflows/cmake-tag.yml | 3 | ||||
-rw-r--r-- | .github/workflows/cmake.yml | 3 | ||||
-rw-r--r-- | .gitmodules | 3 | ||||
-rw-r--r-- | CMakeLists.txt | 36 | ||||
-rw-r--r-- | bench/00-noop.cpp | 15 | ||||
-rw-r--r-- | bench/01-dijkstra.cpp | 67 | ||||
-rw-r--r-- | bench/CMakeLists.txt | 24 | ||||
-rw-r--r-- | bench/dummy.cc | 0 | ||||
-rw-r--r-- | bench/main.cpp | 57 | ||||
-rw-r--r-- | compat/headless.hpp | 12 | ||||
-rw-r--r-- | external/CMakeLists.txt | 34 | ||||
m--------- | external/benchmark | 0 | ||||
-rw-r--r-- | src/path-search-dijkstra.cpp | 2 | ||||
-rw-r--r-- | src/path-search-result.cpp | 2 | ||||
-rw-r--r-- | src/path-search-result.hpp | 11 | ||||
-rw-r--r-- | test/CMakeLists.txt | 15 | ||||
-rw-r--r-- | test/app.hpp | 13 | ||||
-rw-r--r-- | test/dijkstra.cpp | 56 | ||||
-rw-r--r-- | test/main.cpp (renamed from test/app.cpp) | 3 |
19 files changed, 254 insertions, 102 deletions
diff --git a/.github/workflows/cmake-tag.yml b/.github/workflows/cmake-tag.yml index 231241c0..811a4926 100644 --- a/.github/workflows/cmake-tag.yml +++ b/.github/workflows/cmake-tag.yml @@ -37,7 +37,7 @@ jobs: - name: Install Linux dependencies run: | sudo apt -q=2 update - sudo apt install g++-12 gdb ninja-build + sudo apt install g++-12 gdb ninja-build libbenchmark-dev sudo apt -q install libgl1-mesa-dri libgl-dev libglx-dev xorg-dev xvfb libopencv-dev sudo apt -q install libsdl2-dev if: matrix.os == 'ubuntu-22.04' @@ -58,6 +58,7 @@ jobs: cd ${{github.workspace}}/build/install export LD_LIBRARY_PATH="$PWD/lib" ASAN_OPTIONS="detect_leaks=0:abort_on_error=1" xvfb-run gdb -q -batch -x ../../.github/gdbscript.py --args bin/floormat-test </dev/null + xvfb-run gdb -q -batch -x ../../.github/gdbscript.py --args bin/floormat-benchmark if: matrix.os == 'ubuntu-22.04' # - name: Upload build diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index d9690313..dbce62c1 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -38,7 +38,7 @@ jobs: - name: Install Linux dependencies run: | sudo apt -q=2 update - sudo apt install g++-12 gdb ninja-build + sudo apt install g++-12 gdb ninja-build libbenchmark-dev sudo apt -q install libgl1-mesa-dri libgl-dev libglx-dev xorg-dev xvfb libopencv-dev sudo apt -q install libsdl2-dev if: matrix.os == 'ubuntu-22.04' @@ -59,6 +59,7 @@ jobs: cd ${{github.workspace}}/build/install export LD_LIBRARY_PATH="$PWD/lib" ASAN_OPTIONS="detect_leaks=0:abort_on_error=1" xvfb-run gdb -q -batch -x ../../.github/gdbscript.py --args bin/floormat-test </dev/null + xvfb-run gdb -q -batch -x ../../.github/gdbscript.py --args bin/floormat-benchmark if: matrix.os == 'ubuntu-22.04' # - name: Upload build diff --git a/.gitmodules b/.gitmodules index 021954f5..1b59229d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -28,3 +28,6 @@ [submodule "robin-map"] path = external/robin-map url = https://github.com/Tessil/robin-map.git +[submodule "benchmark"] + path = external/benchmark + url = https://github.com/google/benchmark.git diff --git a/CMakeLists.txt b/CMakeLists.txt index c52a2a2c..3527e04f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -177,17 +177,12 @@ else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") endif() -fm_run_hook(fm-userconfig-src) - -if(CMAKE_COMPILER_IS_GNUCXX) - add_compile_options(-Wno-float-equal) -endif() - -if (CMAKE_CXX_COMPILER_ID MATCHES "Clang$") - add_definitions(-D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) - add_compile_options(-Wno-shift-op-parentheses) -elseif(CMAKE_COMPILER_IS_GNUCXX) - add_compile_options(-Wno-subobject-linkage -Wno-parentheses -Wno-overloaded-virtual) +if(APPLE) + set(floormat_headless-library Magnum::WindowlessCglApplication) +elseif(WIN32) + set(floormat_headless-library Magnum::WindowlessWglApplication ntdll) +else() + set(floormat_headless-library Magnum::WindowlessGlxApplication) endif() include_directories(.) @@ -203,13 +198,30 @@ include_directories(SYSTEM "${_fm-json-include-dirs}" ) -#add_subdirectory(demangle) +fm_run_hook(fm-userconfig-src) + +if(CMAKE_COMPILER_IS_GNUCXX) + add_compile_options(-Wno-float-equal) +endif() + +if (CMAKE_CXX_COMPILER_ID MATCHES "Clang$") + add_definitions(-D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) + add_compile_options(-Wno-shift-op-parentheses) +elseif(CMAKE_COMPILER_IS_GNUCXX) + add_compile_options(-Wno-subobject-linkage -Wno-parentheses -Wno-overloaded-virtual) +endif() + add_subdirectory(src) add_subdirectory(main) add_subdirectory(draw) add_subdirectory(serialize) add_subdirectory(editor) add_subdirectory(test) + +find_package(benchmark QUIET) +if(TARGET benchmark::benchmark OR TARGET benchmark) + add_subdirectory(bench) +endif() add_subdirectory(anim-crop-tool) install(DIRECTORY images anim scenery vobj DESTINATION "share/floormat") diff --git a/bench/00-noop.cpp b/bench/00-noop.cpp new file mode 100644 index 00000000..ca84944a --- /dev/null +++ b/bench/00-noop.cpp @@ -0,0 +1,15 @@ +#include <benchmark/benchmark.h> + +#if 0 +namespace { + +void noop(benchmark::State& state) +{ + for (auto _ : state) + (void)0; +} + +BENCHMARK(noop); + +} // namespace +#endif diff --git a/bench/01-dijkstra.cpp b/bench/01-dijkstra.cpp new file mode 100644 index 00000000..b358f1f9 --- /dev/null +++ b/bench/01-dijkstra.cpp @@ -0,0 +1,67 @@ +#include "src/path-search.hpp" +#include "src/path-search-result.hpp" +#include "loader/loader.hpp" +#include <benchmark/benchmark.h> +#include <Corrade/Containers/Optional.h> +#include <Magnum/Math/Functions.h> + +namespace floormat { + +namespace { + +auto A = astar(); +bool first_run = true; + +void Dijkstra(benchmark::State& state) +{ + auto w = world(); + + constexpr auto wcx = 1, wcy = 1, wtx = 8, wty = 8, wox = 3, woy = 3; + constexpr auto max_dist = (uint32_t)(Vector2i(Math::abs(wcx)+1, Math::abs(wcy)+1)*TILE_MAX_DIM*iTILE_SIZE2).length(); + constexpr auto wch = chunk_coords_{wcx, wcy, 0}; + constexpr auto wt = local_coords{wtx, wty}; + constexpr auto wpos = global_coords{wch, wt}; + + auto& ch = w[chunk_coords_{0,0,0}]; + auto& ch2 = w[wch]; + auto metal2 = tile_image_proto{loader.tile_atlas("metal2", {2, 2}, pass_mode::blocked), 0}; + + for (int16_t j = wcy - 1; j <= wcy + 1; j++) + for (int16_t i = wcx - 1; i <= wcx + 1; i++) + { + auto &c = w[chunk_coords_{i, j, 0}]; + for (int k : { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, }) + { + c[{ k, k }].wall_north() = metal2; + c[{ k, k }].wall_west() = metal2; + } + } + + ch2[{ wtx, wty }].wall_west() = metal2; + ch2[{ wtx, wty }].wall_north() = metal2; + ch2[{ wtx+1, wty }].wall_west() = metal2; + ch2[{ wtx, wty -1}].wall_north() = metal2; + + fm_assert(ch.is_passability_modified()); + ch.ensure_passability(); + ch2.ensure_passability(); + + auto run = [&] { + A.Dijkstra(w, + {{0,0,0}, {11,9}}, // from + {wpos, {wox, woy}}, // to + 0, max_dist, {32,32}, // size + first_run ? 1 : 0); + }; + + run(); + first_run = false; + for (auto _ : state) + run(); +} + +} // namespace + +BENCHMARK(Dijkstra); + +} // namespace floormat diff --git a/bench/CMakeLists.txt b/bench/CMakeLists.txt new file mode 100644 index 00000000..ecce9dee --- /dev/null +++ b/bench/CMakeLists.txt @@ -0,0 +1,24 @@ +set(self floormat-benchmark) + +file(GLOB sources "*.cpp" CONFIGURE_ARGS) + +add_library(${self}_o OBJECT "${res}" "${sources}") +add_executable(${self} dummy.cc) + +target_link_libraries(${self}_o PUBLIC + ${floormat_headless-library} + Magnum::Magnum + Magnum::Trade + nlohmann_json::nlohmann_json + fmt::fmt + tsl::robin_map +) + +if(TARGET benchmark::benchmark) + target_link_libraries(${self}_o PUBLIC benchmark::benchmark) +else() + target_link_libraries(${self}_o PUBLIC benchmark) +endif() + +target_link_libraries(${self} PUBLIC ${self}_o floormat-serialize floormat-draw floormat) +install(TARGETS ${self} RUNTIME DESTINATION bin) diff --git a/bench/dummy.cc b/bench/dummy.cc new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/bench/dummy.cc diff --git a/bench/main.cpp b/bench/main.cpp new file mode 100644 index 00000000..80a491ec --- /dev/null +++ b/bench/main.cpp @@ -0,0 +1,57 @@ +#include "loader/loader.hpp" +#include "compat/headless.hpp" +#include <benchmark/benchmark.h> + +namespace floormat { + +namespace { + +#define main bench_main +int bench_main(int argc, char** argv); +BENCHMARK_MAIN(); +#undef main + +struct bench_app final : private FM_APPLICATION +{ + using Application = FM_APPLICATION; + explicit bench_app(int argc, char** argv); + + int exec() override; + ~bench_app(); + + int argc; + char** argv; +}; +bench_app::~bench_app() { loader_::destroy(); } + +int argc_ = 0; // NOLINT + +bench_app::bench_app(int argc, char** argv) : + Application { + {argc_, nullptr}, + Configuration{} + }, + argc{argc}, argv{argv} +{ +} + +int bench_app::exec() +{ + return bench_main(argc, argv); +} + +} // namespace + +} // namespace floormat + +using namespace floormat; + +int main(int argc, char** argv) +{ + int status; + { auto app = bench_app{argc, argv}; + status = app.exec(); + } + loader_::destroy(); + return status; +} diff --git a/compat/headless.hpp b/compat/headless.hpp new file mode 100644 index 00000000..6cf597bc --- /dev/null +++ b/compat/headless.hpp @@ -0,0 +1,12 @@ +#pragma once + +#ifdef __APPLE__ +#include <Magnum/Platform/WindowlessCglApplication.h> +#define FM_APPLICATION Platform::WindowlessCglApplication +#elif defined _WIN32 +#include <Magnum/Platform/WindowlessWglApplication.h> +#define FM_APPLICATION Platform::WindowlessWglApplication +#else +#include <Magnum/Platform/WindowlessGlxApplication.h> +#define FM_APPLICATION Platform::WindowlessGlxApplication +#endif diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 65b79e0d..18913ccc 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -4,12 +4,24 @@ if(NOT DEFINED FLOORMAT_SUBMODULE-SDL2) find_package(SDL2 QUIET) if(SDL2_FOUND) set(FLOORMAT_SUBMODULE-SDL2 OFF CACHE BOOL - "SDL2 as submodule") + "SDL2 as a submodule") endif() endif() set(FLOORMAT_SUBMODULE-SDL2 ON CACHE BOOL "SDL2 as submodule") + +if(NOT DEFINED FLOORMAT_SUBMODULE-BENCHMARK) + find_package(benchmark QUIET) + if(benchmark_FOUND) + set(FLOORMAT_SUBMODULE-BENCHMARK OFF CACHE BOOL + "Benchmark as a submodule") + endif() +endif() + +set(FLOORMAT_SUBMODULE-BENCHMARK ON CACHE BOOL + "Benchmark as a submodule") + set(FLOORMAT_SUBMODULE-DEPENDENCIES ON CACHE BOOL "Use dependencies included in the source directory (needs git submodule update --init).") @@ -234,6 +246,23 @@ if(FLOORMAT_SUBMODULE-DEPENDENCIES) endif() endfunction() + function(fm_add_benchmark) + set(BUILD_SHARED_LIBS 1) + if(WIN32) + set(HAVE_STD_REGEX 1) + endif() + set(BENCHMARK_ENABLE_TESTING OFF) + set(BENCHMARK_ENABLE_EXCEPTIONS ON) + set(BENCHMARK_ENABLE_LTO OFF) + set(BENCHMARK_ENABLE_WERROR OFF) + set(BENCHMARK_FORCE_WERROR OFF) + set(BENCHMARK_ENABLE_INSTALL OFF) + set(BENCHMARK_ENABLE_DOXYGEN OFF) + set(BENCHMARK_INSTALL_DOCS OFF) + set(BENCHMARK_ENABLE_GTEST_TESTS OFF) + add_subdirectory(benchmark ${system}) + endfunction() + function(fm_add_luajit) set(CMAKE_C_STANDARD 11) set(CMAKE_C_EXTENSIONS 1) @@ -256,6 +285,9 @@ if(FLOORMAT_SUBMODULE-DEPENDENCIES) if(MAGNUM_BUILD_TESTS OR CORRADE_BUILD_TESTS AND NOT DEFINED CORRADE_TESTSUITE_TEST_TARGET) sets(STRING CORRADE_TESTSUITE_TEST_TARGET corrade-test) endif() + if(FLOORMAT_SUBMODULE-BENCHMARK) + fm_add_benchmark() + endif() fm_add_sdl2() #fm_add_luajit() if(MSVC) diff --git a/external/benchmark b/external/benchmark new file mode 160000 +Subproject ca8d0f7b613ac915cd6b161ab01b7be449d1e1c diff --git a/src/path-search-dijkstra.cpp b/src/path-search-dijkstra.cpp index 77c3d8b6..a40d79ad 100644 --- a/src/path-search-dijkstra.cpp +++ b/src/path-search-dijkstra.cpp @@ -198,7 +198,7 @@ path_search_result astar::Dijkstra(world& w, point from_, point to_, object_id o return {}; path_search_result result; - auto& path = result._node->vec; path.clear(); + auto& path = result.path(); path.clear(); indexes[from_] = 0; nodes.push_back({.dist = 0, .coord = from, .offset = from_offset }); diff --git a/src/path-search-result.cpp b/src/path-search-result.cpp index 9e62a30f..26fcd98d 100644 --- a/src/path-search-result.cpp +++ b/src/path-search-result.cpp @@ -69,5 +69,7 @@ auto path_search_result::operator[](size_t index) const -> const pair& fm_debug_assert(index < _node->vec.size()); return data()[index]; } +auto path_search_result::path() -> std::vector<pair>& { fm_assert(_node); return _node->vec; } +auto path_search_result::path() const -> const std::vector<pair>& { fm_assert(_node); return _node->vec; } } // namespace floormat diff --git a/src/path-search-result.hpp b/src/path-search-result.hpp index 90a4ba3d..92484c63 100644 --- a/src/path-search-result.hpp +++ b/src/path-search-result.hpp @@ -8,8 +8,6 @@ namespace floormat { struct path_search_result final { - friend class path_search; - friend struct astar; friend struct test_app; struct pair { global_coords pos; Vector2 offset; }; @@ -18,14 +16,18 @@ struct path_search_result final const pair& operator[](size_t index) const; size_t size() const; + std::vector<pair>& path(); + const std::vector<pair>& path() const; explicit operator ArrayView<const pair>() const; explicit operator bool() const; -private: fm_DECLARE_DEFAULT_MOVE_ASSIGNMENT_(path_search_result); path_search_result(const path_search_result& x) noexcept; path_search_result& operator=(const path_search_result& x) noexcept; + path_search_result(); + ~path_search_result() noexcept; +private: static constexpr size_t min_length = TILE_MAX_DIM*2; struct node @@ -45,9 +47,6 @@ private: static std::unique_ptr<node> _pool; // NOLINT(*-avoid-non-const-global-variables) - path_search_result(); - ~path_search_result() noexcept; - std::unique_ptr<node> _node; }; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0d713de5..f8048278 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,15 +4,12 @@ file(GLOB sources "*.cpp" CONFIGURE_ARGS) file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/test") add_library(${self}_o OBJECT "${sources}") -target_link_libraries(${self}_o PUBLIC Magnum::GL Magnum::Trade nlohmann_json::nlohmann_json fmt::fmt tsl::robin_map) - -if(APPLE) - target_link_libraries(${self}_o PUBLIC Magnum::WindowlessCglApplication) -elseif(WIN32) - target_link_libraries(${self}_o PUBLIC Magnum::WindowlessWglApplication ntdll) -else() - target_link_libraries(${self}_o PUBLIC Magnum::WindowlessGlxApplication) -endif() +target_link_libraries(${self}_o PUBLIC + ${floormat_headless-library} + Magnum::GL Magnum::Trade + nlohmann_json::nlohmann_json + fmt::fmt tsl::robin_map +) add_executable(${self} dummy.cc) target_link_libraries(${self} ${self}_o floormat-serialize floormat) diff --git a/test/app.hpp b/test/app.hpp index 0822e68f..630acf02 100644 --- a/test/app.hpp +++ b/test/app.hpp @@ -1,19 +1,9 @@ #pragma once #undef FM_NO_DEBUG #include "compat/assert.hpp" +#include "compat/headless.hpp" #include <Magnum/Magnum.h> -#ifdef __APPLE__ -#include <Magnum/Platform/WindowlessCglApplication.h> -#define FM_APPLICATION Platform::WindowlessCglApplication -#elif defined _WIN32 -#include <Magnum/Platform/WindowlessWglApplication.h> -#define FM_APPLICATION Platform::WindowlessWglApplication -#else -#include <Magnum/Platform/WindowlessGlxApplication.h> -#define FM_APPLICATION Platform::WindowlessGlxApplication -#endif - namespace floormat { struct chunk_coords; @@ -44,7 +34,6 @@ struct test_app final : private FM_APPLICATION static void test_path_search(); static void test_hash(); static void test_path_search_node_pool(); - static void test_dijkstra(); static void zzz_test_misc(); }; } // namespace floormat diff --git a/test/dijkstra.cpp b/test/dijkstra.cpp index 301257b1..e69de29b 100644 --- a/test/dijkstra.cpp +++ b/test/dijkstra.cpp @@ -1,56 +0,0 @@ -#include "app.hpp" -#include "bench.hpp" -#include "src/path-search.hpp" -#include "loader/loader.hpp" -#include <Magnum/Math/Functions.h> - -namespace floormat { - -void test_app::test_dijkstra() -{ - auto w = world(); - auto a = astar(); - - constexpr auto wcx = 1, wcy = 1, wtx = 8, wty = 8, wox = 3, woy = 3; - constexpr auto max_dist = (uint32_t)(Vector2i(Math::abs(wcx)+1, Math::abs(wcy)+1)*TILE_MAX_DIM*iTILE_SIZE2).length(); - constexpr auto wch = chunk_coords_{wcx, wcy, 0}; - constexpr auto wt = local_coords{wtx, wty}; - constexpr auto wpos = global_coords{wch, wt}; - - auto& ch = w[chunk_coords_{0,0,0}]; -#if 1 - auto& ch2 = w[wch]; - auto metal2 = tile_image_proto{loader.tile_atlas("metal2", {2, 2}, pass_mode::blocked), 0}; - - ch[{4, 4}].wall_west() = metal2; - ch[{4, 4}].wall_north() = metal2; - - ch2[{ wtx, wty }].wall_west() = metal2; - ch2[{ wtx, wty }].wall_north() = metal2; - ch2[{ wtx+1, wty }].wall_west() = metal2; - ch2[{ wtx, wty -1}].wall_north() = metal2; -#endif - - fm_assert(ch.is_passability_modified()); - - auto do_bench = [&](int count, int debug) { - for (int i = 0; i < count; i++) - a.Dijkstra(w, - {{0,0,0}, {11,9}}, // from - {wpos, {wox, woy}}, // to - 0, max_dist, {32,32}, // size - debug); - }; - - static constexpr int iters = 10; - if constexpr (iters > 1) - do_bench(1, 1); -#if 1 - for (int i = 0; i < iters; i++) - bench_run("Dijkstra", [&] { - do_bench(1, iters == 1); - }); -#endif -} - -} // namespace floormat diff --git a/test/app.cpp b/test/main.cpp index 3e1f7f82..c6ef7557 100644 --- a/test/app.cpp +++ b/test/main.cpp @@ -34,9 +34,6 @@ int test_app::exec() test_math(); test_hash(); test_path_search_node_pool(); - - test_dijkstra(); - zzz_test_misc(); return 0; |