diff --git a/include/ylt/metric/summary_impl.hpp b/include/ylt/metric/summary_impl.hpp index ce853af64..081927a4d 100644 --- a/include/ylt/metric/summary_impl.hpp +++ b/include/ylt/metric/summary_impl.hpp @@ -10,6 +10,10 @@ #include #include +#ifdef SUMMARY_DEBUG_STABLE_TEST +#include "ylt/easylog.hpp" +#endif + namespace ylt::metric::detail { template @@ -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& 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_) { diff --git a/src/metric/benchmark/bench.hpp b/src/metric/benchmark/bench.hpp index b464df58d..4306bc673 100644 --- a/src/metric/benchmark/bench.hpp +++ b/src/metric/benchmark/bench.hpp @@ -25,7 +25,7 @@ struct bench_clock_t { std::chrono::steady_clock::time_point start_; }; -template +template void bench_mixed_impl(IMPL& impl, WRITE_OP&& op, size_t thd_num, std::chrono::seconds duration) { ylt::metric::summary_t lantency_summary( @@ -41,40 +41,46 @@ void bench_mixed_impl(IMPL& impl, WRITE_OP&& op, size_t thd_num, auto dur = clock.duration(); while (!stop && dur < duration + 1s) { op(); - auto new_dur = clock.duration(); - lantency_summary.observe((new_dur - dur).count() / 1000.0f); - dur = new_dur; + if constexpr (need_latch) { + auto new_dur = clock.duration(); + 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(); } @@ -227,7 +233,7 @@ inline void bench_dynamic_summary_serialize(size_t COUNT, COUNT, to_json); } -template +template void bench_write_impl(IMPL& impl, OP&& op, size_t thd_num, std::chrono::seconds duration) { std::atomic stop = false; @@ -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, diff --git a/src/metric/tests/CMakeLists.txt b/src/metric/tests/CMakeLists.txt index 0c37b056f..704598187 100644 --- a/src/metric/tests/CMakeLists.txt +++ b/src/metric/tests/CMakeLists.txt @@ -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) diff --git a/src/metric/tests/parallel_test2.cpp b/src/metric/tests/parallel_test2.cpp new file mode 100644 index 000000000..165c99985 --- /dev/null +++ b/src/metric/tests/parallel_test2.cpp @@ -0,0 +1,50 @@ + +#define SUMMARY_DEBUG_STABLE_TEST // max_age=1ms +#include +#include + +#include "../benchmark/bench.hpp" +#include "doctest.h" +#include "ylt/metric.hpp" + +TEST_CASE("test high press stable r/w with 1ms") { + std::vector 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( + 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 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( + 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); +} \ No newline at end of file