Skip to content

Commit

Permalink
Add summary stable test (#888)
Browse files Browse the repository at this point in the history
* add stable test for summary

* fix msvc
  • Loading branch information
poor-circle authored Jan 26, 2025
1 parent d46f1c0 commit 56fbbba
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 27 deletions.
20 changes: 17 additions & 3 deletions include/ylt/metric/summary_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
#include <type_traits>
#include <vector>

#ifdef SUMMARY_DEBUG_STABLE_TEST
#include "ylt/easylog.hpp"
#endif

namespace ylt::metric::detail {

template <typename uint_type, std::size_t frac_bit = 6>
Expand Down Expand Up @@ -331,13 +335,23 @@ class summary_impl {
data_copy.inc();
}
return result;
}
};
#ifdef SUMMARY_DEBUG_STABLE_TEST
static inline constexpr size_t ms_per_second = 1;
#else
static inline constexpr size_t ms_per_second = 1000;
#endif

summary_impl(std::vector<double>& rate,
std::chrono::seconds refresh_time = std::chrono::seconds{0})
: rate_(rate),
refresh_time_(refresh_time.count() * 1000 / 2),
tp_(std::chrono::steady_clock::now().time_since_epoch().count()){};
refresh_time_(refresh_time.count() * ms_per_second / 2),
tp_(std::chrono::steady_clock::now().time_since_epoch().count()) {
#ifdef SUMMARY_DEBUG_STABLE_TEST
ELOG_WARN << "summary max_age is ms now! dont use it in production! It's "
"just for test";
#endif
};

~summary_impl() {
for (auto& data : data_) {
Expand Down
57 changes: 33 additions & 24 deletions src/metric/benchmark/bench.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct bench_clock_t {
std::chrono::steady_clock::time_point start_;
};

template <typename IMPL, typename WRITE_OP>
template <bool need_latch = true, typename IMPL, typename WRITE_OP>
void bench_mixed_impl(IMPL& impl, WRITE_OP&& op, size_t thd_num,
std::chrono::seconds duration) {
ylt::metric::summary_t lantency_summary(
Expand All @@ -41,40 +41,46 @@ void bench_mixed_impl(IMPL& impl, WRITE_OP&& op, size_t thd_num,
auto dur = clock.duration<std::chrono::microseconds>();
while (!stop && dur < duration + 1s) {
op();
auto new_dur = clock.duration<std::chrono::microseconds>();
lantency_summary.observe((new_dur - dur).count() / 1000.0f);
dur = new_dur;
if constexpr (need_latch) {
auto new_dur = clock.duration<std::chrono::microseconds>();
lantency_summary.observe((new_dur - dur).count() / 1000.0f);
dur = new_dur;
}
}
}));
}
std::string s;

std::size_t tot = 0;
bench_clock_t clock2;
int64_t serialze_cnt = 0;
do {
s.clear();
impl.serialize(s);
tot += s.size();
++serialze_cnt;
} while (clock2.duration() < duration);
auto total_ms = clock.duration();
stop = true;
if constexpr (requires { impl.size(); }) {
std::cout << "size:" << impl.size() << "\n";
if constexpr (need_latch) {
if constexpr (requires { impl.size(); }) {
std::cout << "size:" << impl.size() << "\n";
}
std::cout << "serialize bytes total:" << tot << std::endl;
std::cout << "run " << total_ms.count() << "ms\n";
uint64_t cnt;
double sum;
auto result = lantency_summary.get_rates(sum, cnt);
auto seconds = total_ms.count() / 1000.0;
auto qps = 1.0 * cnt / seconds;
std::cout << "write thd num: " << thd_num << ", write qps: " << (int64_t)qps
<< "\n";
std::cout << "serialize qps:" << 1000.0 * serialze_cnt / total_ms.count()
<< ", str size=" << s.size() << "\n";
s = "";
lantency_summary.serialize(s);
std::cout << s;
}

std::cout << "run " << total_ms.count() << "ms\n";
uint64_t cnt;
double sum;
auto result = lantency_summary.get_rates(sum, cnt);
auto seconds = total_ms.count() / 1000.0;
auto qps = 1.0 * cnt / seconds;
std::cout << "write thd num: " << thd_num << ", write qps: " << (int64_t)qps
<< "\n";
std::cout << "serialize qps:" << 1000.0 * serialze_cnt / total_ms.count()
<< ", str size=" << s.size() << "\n";
s = "";
lantency_summary.serialize(s);
std::cout << s;
for (auto& thd : vec) {
thd.join();
}
Expand Down Expand Up @@ -227,7 +233,7 @@ inline void bench_dynamic_summary_serialize(size_t COUNT,
COUNT, to_json);
}

template <typename IMPL, typename OP>
template <bool need_output = true, typename IMPL, typename OP>
void bench_write_impl(IMPL& impl, OP&& op, size_t thd_num,
std::chrono::seconds duration) {
std::atomic<bool> stop = false;
Expand All @@ -247,13 +253,16 @@ void bench_write_impl(IMPL& impl, OP&& op, size_t thd_num,
}
std::this_thread::sleep_for(duration);
stop = true;
std::cout << "run " << clock.duration().count() << "ms\n";
auto tm = clock.duration().count();
double qps = 0;
for (auto& thd : vec) {
qps += thd.get();
}
qps /= (clock.duration().count() / 1000.0);
std::cout << "thd num: " << thd_num << ", qps: " << (int64_t)qps << "\n";
if constexpr (need_output) {
std::cout << "run " << clock.duration().count() << "ms\n";
qps /= (clock.duration().count() / 1000.0);
std::cout << "thd num: " << thd_num << ", qps: " << (int64_t)qps << "\n";
}
}

inline void bench_static_counter_write(size_t thd_num,
Expand Down
1 change: 1 addition & 0 deletions src/metric/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output/tests)
add_executable(metric_test
test_metric.cpp
parallel_test.cpp
parallel_test2.cpp
)
check_asan(HAS_ASAN)
if (has_asan)
Expand Down
50 changes: 50 additions & 0 deletions src/metric/tests/parallel_test2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

#define SUMMARY_DEBUG_STABLE_TEST // max_age=1ms
#include <chrono>
#include <thread>

#include "../benchmark/bench.hpp"
#include "doctest.h"
#include "ylt/metric.hpp"

TEST_CASE("test high press stable r/w with 1ms") {
std::vector<std::thread> works;
for (int i = 0; i < std::thread::hardware_concurrency() * 10; i++) {
works.emplace_back(std::thread{[]() {
ylt::metric::summary_t summary("summary mixed test", "",
{0.5, 0.9, 0.95, 0.99, 0.995}, 1s);
bench_mixed_impl<false>(
summary,
[&]() {
summary.observe(get_random(100));
},
1, 10s);
}});
}
for (auto& e : works) {
e.join();
}
}

TEST_CASE("test high press stable r with 1ms") {
std::vector<std::thread> works;
for (int i = 0; i < std::thread::hardware_concurrency() * 10; i++) {
works.emplace_back(std::thread{[]() {
ylt::metric::summary_t summary("summary mixed test", "",
{0.5, 0.9, 0.95, 0.99, 0.995}, 1s);
bench_write_impl<false>(
summary,
[&]() {
summary.observe(get_random(100));
},
2, 10s);
}});
}
for (auto& e : works) {
e.join();
}
}

TEST_CASE("test high parallel perform test with 3ms") {
bench_static_summary_mixed(std::thread::hardware_concurrency() * 4, 3s);
}

0 comments on commit 56fbbba

Please sign in to comment.