summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/cmake-tag.yml3
-rw-r--r--.github/workflows/cmake.yml3
-rw-r--r--.gitmodules3
-rw-r--r--CMakeLists.txt36
-rw-r--r--bench/00-noop.cpp15
-rw-r--r--bench/01-dijkstra.cpp67
-rw-r--r--bench/CMakeLists.txt24
-rw-r--r--bench/dummy.cc0
-rw-r--r--bench/main.cpp57
-rw-r--r--compat/headless.hpp12
-rw-r--r--external/CMakeLists.txt34
m---------external/benchmark0
-rw-r--r--src/path-search-dijkstra.cpp2
-rw-r--r--src/path-search-result.cpp2
-rw-r--r--src/path-search-result.hpp11
-rw-r--r--test/CMakeLists.txt15
-rw-r--r--test/app.hpp13
-rw-r--r--test/dijkstra.cpp56
-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;