Util hpp
This commit is contained in:
@@ -50,7 +50,7 @@ VARIANT ?= baseline
|
|||||||
VARIANT_SRC := variant_$(VARIANT).cpp
|
VARIANT_SRC := variant_$(VARIANT).cpp
|
||||||
|
|
||||||
SRC := main.cpp $(VARIANT_SRC)
|
SRC := main.cpp $(VARIANT_SRC)
|
||||||
HEADERS := board.hpp forces.hpp pedestrian.hpp vector2d.hpp constants.hpp social_force.hpp
|
HEADERS := board.hpp forces.hpp pedestrian.hpp vector2d.hpp constants.hpp social_force.hpp util.hpp
|
||||||
|
|
||||||
TEST_SRC := test_vector2d.cpp test_board.cpp test_forces.cpp $(VARIANT_SRC)
|
TEST_SRC := test_vector2d.cpp test_board.cpp test_forces.cpp $(VARIANT_SRC)
|
||||||
TEST_TARGET := run_tests
|
TEST_TARGET := run_tests
|
||||||
@@ -72,6 +72,14 @@ MP4 ?= simulation.mp4 # Default visualization video output file.
|
|||||||
# Use RANDOM_SEED=1 to seed from std::random_device.
|
# Use RANDOM_SEED=1 to seed from std::random_device.
|
||||||
RANDOM_SEED ?= 0
|
RANDOM_SEED ?= 0
|
||||||
|
|
||||||
|
# flopcounter enabled/disabled, no impact on runtime when running with 0
|
||||||
|
# default = 0 = disabled
|
||||||
|
# 1 = enabled
|
||||||
|
# if set to 0 --> compiler will swap all function calls with ((void)0)
|
||||||
|
# using -O3 will remove all ((void)0)
|
||||||
|
FLOPCOUNT ?= 0
|
||||||
|
CXXFLAGS += -DFLOPCOUNT=$(FLOPCOUNT)
|
||||||
|
|
||||||
# Pass random-seeding mode to the C++ code.
|
# Pass random-seeding mode to the C++ code.
|
||||||
CXXFLAGS += -DRANDOM_SEED=$(RANDOM_SEED)
|
CXXFLAGS += -DRANDOM_SEED=$(RANDOM_SEED)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// This function exactly tracks the flop count for each function
|
||||||
|
// Usage
|
||||||
|
// compile, e.g.:
|
||||||
|
// make run-bench FLOPCOUNT=1 N_P=60 N_ITER=4000
|
||||||
|
// if not compiled with FLOPCOUNT all associated function are written as ((void)0) and removed when using -O3 flag
|
||||||
|
// In code:
|
||||||
|
// FLOP_RECORD(flop_counter::<FUNC_NAME>, int add, int mult, int div, int sqrt, int exp)
|
||||||
|
// <FUNC_NAME> see FunctionId in util.hpp
|
||||||
|
// Print out metrics:
|
||||||
|
// flop_counter::report();
|
||||||
|
// flop_counter::report_csv();
|
||||||
|
// Additonal remarks:
|
||||||
|
// make sure to call flop_counter::reset(); after the warmup phase, because else counting flops double
|
||||||
|
// make sure to import util.hpp #include "util.hpp"
|
||||||
|
|
||||||
|
// get the cycles count per flop
|
||||||
|
#include "constants.hpp" // cost_add, cost_mult, cost_div, cost_sqrt, cost_exp
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
#ifndef FLOPCOUNT
|
||||||
|
#define FLOPCOUNT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace flop_counter {
|
||||||
|
|
||||||
|
// defined functions, add new one if needed
|
||||||
|
// create enumeration, which must be in sync with kFunctionNames
|
||||||
|
enum FunctionId : int {
|
||||||
|
FN_W,
|
||||||
|
FN_ACCELERATION,
|
||||||
|
FN_PEDESTRIAN_REPULSION,
|
||||||
|
FN_OBSTACLE_REPULSION,
|
||||||
|
FN_NEAREST_OBSTACLE_POINT,
|
||||||
|
FN_UPDATE,
|
||||||
|
FN_OTHER,
|
||||||
|
FN_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
// track the flop count for each function separately
|
||||||
|
// add more functions, do not mix up the order
|
||||||
|
inline constexpr std::array<const char *, FN_COUNT> kFunctionNames = {
|
||||||
|
"w",
|
||||||
|
"acceleration_term_dt",
|
||||||
|
"pedestrian_repulsion_dt",
|
||||||
|
"obstacle_repulsion_dt",
|
||||||
|
"find_nearest_obstacle_point",
|
||||||
|
"update_pass",
|
||||||
|
"other",
|
||||||
|
};
|
||||||
|
|
||||||
|
#if FLOPCOUNT
|
||||||
|
|
||||||
|
// for each function store add, mult, div, sqrt, exp
|
||||||
|
inline std::uint64_t counters[FN_COUNT][5]{};
|
||||||
|
|
||||||
|
// update
|
||||||
|
inline void record(FunctionId fn, std::uint64_t add, std::uint64_t mult,
|
||||||
|
std::uint64_t div, std::uint64_t sqrt_n,
|
||||||
|
std::uint64_t exp_n) {
|
||||||
|
counters[fn][0] += add;
|
||||||
|
counters[fn][1] += mult;
|
||||||
|
counters[fn][2] += div;
|
||||||
|
counters[fn][3] += sqrt_n;
|
||||||
|
counters[fn][4] += exp_n;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set all metrics to 0
|
||||||
|
inline void reset() {
|
||||||
|
for (int f = 0; f < FN_COUNT; ++f)
|
||||||
|
for (int o = 0; o < 5; ++o)
|
||||||
|
counters[f][o] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void report() {
|
||||||
|
std::printf("\n=== flop count ===\n");
|
||||||
|
std::printf("%-30s %12s %12s %12s %12s %12s %16s\n",
|
||||||
|
"function", "add", "mult", "div", "sqrt", "exp", "per function");
|
||||||
|
long double total = 0;
|
||||||
|
for (int f = 0; f < FN_COUNT; ++f) {
|
||||||
|
auto a = counters[f][0], m = counters[f][1], d = counters[f][2],
|
||||||
|
s = counters[f][3], e = counters[f][4];
|
||||||
|
long double w = a * (long double)cost_add + m * (long double)cost_mult
|
||||||
|
+ d * (long double)cost_div + s * (long double)cost_sqrt
|
||||||
|
+ e * (long double)cost_exp;
|
||||||
|
total += w;
|
||||||
|
if ((a | m | d | s | e) == 0) continue;
|
||||||
|
std::printf("%-30s %12llu %12llu %12llu %12llu %12llu %16.2Lf\n",
|
||||||
|
kFunctionNames[f],
|
||||||
|
(unsigned long long)a, (unsigned long long)m,
|
||||||
|
(unsigned long long)d, (unsigned long long)s,
|
||||||
|
(unsigned long long)e, w);
|
||||||
|
}
|
||||||
|
std::printf("%-30s %12s %12s %12s %12s %12s %16.2Lf\n",
|
||||||
|
"TOTAL", "", "", "", "", "", total);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FLOP_RECORD(fn, a, m, d, s, e) \
|
||||||
|
::flop_counter::record((fn), (a), (m), (d), (s), (e))
|
||||||
|
|
||||||
|
#else // FLOPCOUNT == 0 -> no-op, removed by -O3
|
||||||
|
|
||||||
|
inline void record(FunctionId, std::uint64_t, std::uint64_t, std::uint64_t,
|
||||||
|
std::uint64_t, std::uint64_t) {}
|
||||||
|
inline void reset() {}
|
||||||
|
inline void report() {}
|
||||||
|
|
||||||
|
#define FLOP_RECORD(fn, a, m, d, s, e) ((void)0)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace flop_counter
|
||||||
Reference in New Issue
Block a user