From 429c098023b893dab9d30cf8dd170d61f9af5f2c Mon Sep 17 00:00:00 2001 From: HÃ¥vard Pettersen Date: Mon, 24 Jan 2022 11:55:59 +0000 Subject: use pthread clock for total cpu usage as well --- vespalib/src/tests/cpu_usage/cpu_usage_test.cpp | 18 ++++++++---------- vespalib/src/vespa/vespalib/util/cpu_usage.cpp | 14 ++++++-------- vespalib/src/vespa/vespalib/util/cpu_usage.h | 10 ++-------- 3 files changed, 16 insertions(+), 26 deletions(-) (limited to 'vespalib') diff --git a/vespalib/src/tests/cpu_usage/cpu_usage_test.cpp b/vespalib/src/tests/cpu_usage/cpu_usage_test.cpp index 6bedfb5013e..fde02dc8435 100644 --- a/vespalib/src/tests/cpu_usage/cpu_usage_test.cpp +++ b/vespalib/src/tests/cpu_usage/cpu_usage_test.cpp @@ -60,28 +60,26 @@ void verify_sampling(size_t thread_id, size_t num_threads, std::vector TEST_BARRIER(); // #1 auto t0 = steady_clock::now(); std::vector pre_usage = sample(samplers); - auto pre_total = cpu_usage::RUsage::sample(); + auto pre_total = cpu_usage::total_cpu_usage(); TEST_BARRIER(); // #2 TEST_BARRIER(); // #3 auto t1 = steady_clock::now(); std::vector post_usage = sample(samplers); - auto post_total = cpu_usage::RUsage::sample(); + auto post_total = cpu_usage::total_cpu_usage(); TEST_BARRIER(); // #4 double wall = to_s(t1 - t0); std::vector load(4, 0.0); for (size_t i = 0; i < 4; ++i) { load[i] = to_s(post_usage[i] - pre_usage[i]) / wall; } - double user_load = to_s(post_total.user - pre_total.user) / wall; - double system_load = to_s(post_total.system - pre_total.system) / wall; - double total_load = to_s(post_total.total() - pre_total.total()) / wall; + double total_load = to_s(post_total - pre_total) / wall; EXPECT_GREATER(load[3], load[0]); // NB: cannot expect total_load to be greater than load[3] // here due to mock loads being 'as expected' while valgrind // will cut all loads in about half. EXPECT_GREATER(total_load, load[0]); - fprintf(stderr, "loads: { %.2f, %.2f, %.2f, %.2f }\n", load[0], load[1], load[2], load[3]); - fprintf(stderr, "total load: %.2f (user: %.2f, system: %.2f)\n", total_load, user_load, system_load); + fprintf(stderr, "loads: { %.3f, %.3f, %.3f, %.3f }\n", load[0], load[1], load[2], load[3]); + fprintf(stderr, "total load: %.3f\n", total_load); } else { int idx = (thread_id - 1); double target_load = double(thread_id - 1) / (num_threads - 2); @@ -114,9 +112,9 @@ TEST("measure thread CPU clock overhead") { fprintf(stderr, "approx overhead per sample (thread CPU clock): %f us\n", min_time_us); } -TEST("measure RUsage overhead") { +TEST("measure total cpu usage overhead") { duration d; - double min_time_us = BenchmarkTimer::benchmark([&d]() noexcept { d = cpu_usage::RUsage::sample().total(); }, budget) * 1000000.0; + double min_time_us = BenchmarkTimer::benchmark([&d]() noexcept { d = cpu_usage::total_cpu_usage(); }, budget) * 1000000.0; fprintf(stderr, "approx overhead per RUsage sample: %f us\n", min_time_us); } @@ -437,7 +435,7 @@ void do_sample_cpu_usage(const EndTime &end_time) { if (!body.empty()) { body.append(", "); } - body.append(fmt("%s: %.2f", CpuUsage::name_of(CpuUsage::Category(i)).c_str(), load[i])); + body.append(fmt("%s: %.3f", CpuUsage::name_of(CpuUsage::Category(i)).c_str(), load[i])); } fprintf(stderr, "CPU: %s\n", body.c_str()); } diff --git a/vespalib/src/vespa/vespalib/util/cpu_usage.cpp b/vespalib/src/vespa/vespalib/util/cpu_usage.cpp index 345da66cc39..5609b0d8d09 100644 --- a/vespalib/src/vespa/vespalib/util/cpu_usage.cpp +++ b/vespalib/src/vespa/vespalib/util/cpu_usage.cpp @@ -46,13 +46,11 @@ public: } // -RUsage -RUsage::sample() noexcept -{ - rusage usage; - memset(&usage, 0, sizeof(usage)); - getrusage(RUSAGE_SELF, &usage); - return {from_timeval(usage.ru_utime), from_timeval(usage.ru_stime)}; +duration total_cpu_usage() noexcept { + timespec ts; + memset(&ts, 0, sizeof(ts)); + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts); + return from_timespec(ts); } ThreadSampler::UP create_thread_sampler(bool force_mock_impl, double expected_load) { @@ -224,7 +222,7 @@ CpuUsage::do_sample() my_sample.merge(_usage); _usage = my_sample; } - auto total = cpu_usage::RUsage::sample().total(); + auto total = cpu_usage::total_cpu_usage(); for (size_t i = 0; i < index_of(Category::OTHER); ++i) { total -= my_sample[i]; } diff --git a/vespalib/src/vespa/vespalib/util/cpu_usage.h b/vespalib/src/vespa/vespalib/util/cpu_usage.h index b0e9f60311b..3c30937151c 100644 --- a/vespalib/src/vespa/vespalib/util/cpu_usage.h +++ b/vespalib/src/vespa/vespalib/util/cpu_usage.h @@ -13,15 +13,9 @@ namespace vespalib { namespace cpu_usage { /** - * Uses getrusage to sample the total amount of user and system cpu - * time used so far. + * Samples the total CPU usage of this process so far. **/ -struct RUsage { - duration user; - duration system; - duration total() const { return user + system; } - static RUsage sample() noexcept; -}; +duration total_cpu_usage() noexcept; /** * Samples the total CPU usage of the thread that created it. Note -- cgit v1.2.3