g3log-latency.cpp 3.82 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
#include <thread>
#include <vector>
#include <atomic>
#include <iostream>
#include <chrono>
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <fstream>
#include <cstdio>
#include <map>
#include <numeric>
#include <functional>
#include <thread>
#include "utils.h"
#include <g3log/g3log.hpp>
#include <g3log/logworker.hpp>


namespace
{
const uint64_t g_iterations = 1000000;


std::atomic<size_t> g_counter = {0};


void MeasurePeakDuringLogWrites(const size_t id, std::vector<uint64_t>& result)
{

    while (true)
    {
        const size_t value_now = ++g_counter;
        if (value_now > g_iterations)
        {
            return;
        }

        auto start_time = std::chrono::high_resolution_clock::now();
gabime's avatar
gabime committed
41
        LOGF(INFO, "Some text to log for thread: %ld", id);
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
        auto stop_time = std::chrono::high_resolution_clock::now();
        uint64_t time_us = std::chrono::duration_cast<std::chrono::microseconds>(stop_time - start_time).count();
        result.push_back(time_us);
    }
}



void PrintResults(const std::map<size_t, std::vector<uint64_t>>& threads_result, size_t total_us)
{

    std::vector<uint64_t> all_measurements;
    all_measurements.reserve(g_iterations);
    for (auto& t_result : threads_result)
    {
        all_measurements.insert(all_measurements.end(), t_result.second.begin(), t_result.second.end());
    }

    // calc worst latenct
    auto worst = *std::max_element(all_measurements.begin(), all_measurements.end());
gabime's avatar
gabime committed
62

63 64 65 66 67
    // calc avg
    auto total = accumulate(begin(all_measurements), end(all_measurements), 0, std::plus<uint64_t>());
    auto avg = double(total)/all_measurements.size();

    std::cout << "[g3log]  worst: " <<  std::setw(10) << std::right << worst << "\tAvg: "  << avg << "\tTotal: "  <<  utils::format(total_us) << " us" << std::endl;
gabime's avatar
gabime committed
68

69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
}
}// anonymous


// The purpose of this test is NOT to see how fast
// each thread can possibly write. It is to see what
// the worst latency is for writing a log entry
//
// In the test 1 million log entries will be written
// an atomic counter is used to give each thread what
// it is to write next. The overhead of atomic
// synchronization between the threads are not counted in the worst case latency
int main(int argc, char** argv)
{
    size_t number_of_threads {0};
    if (argc == 2)
    {
        number_of_threads = atoi(argv[1]);
    }
    if (argc != 2 || number_of_threads == 0)
    {
        std::cerr << "USAGE is: " << argv[0] << " number_threads" << std::endl;
        return 1;
    }


    std::vector<std::thread> threads(number_of_threads);
    std::map<size_t, std::vector<uint64_t>> threads_result;

    for (size_t idx = 0; idx < number_of_threads; ++idx)
    {
        // reserve to 1 million for all the result
        // it's a test so  let's not care about the wasted space
        threads_result[idx].reserve(g_iterations);
    }

    const std::string g_path = "./" ;
    const std::string  g_prefix_log_name = "g3log-performance-";
    const std::string  g_measurement_dump = g_path + g_prefix_log_name + "_RESULT.txt";

gabime's avatar
gabime committed
109
    auto worker = g3::LogWorker::createLogWorker();
110 111
    auto handle= worker->addDefaultLogger(argv[0], "g3log.txt");
    g3::initializeLogging(worker.get());
gabime's avatar
gabime committed
112

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
    auto start_time_application_total = std::chrono::high_resolution_clock::now();
    for (uint64_t idx = 0; idx < number_of_threads; ++idx)
    {
        threads[idx] = std::thread(MeasurePeakDuringLogWrites, idx, std::ref(threads_result[idx]));
    }
    for (size_t idx = 0; idx < number_of_threads; ++idx)
    {
        threads[idx].join();
    }
    auto stop_time_application_total = std::chrono::high_resolution_clock::now();

    uint64_t total_time_in_us = std::chrono::duration_cast<std::chrono::microseconds>(stop_time_application_total - start_time_application_total).count();
    PrintResults(threads_result, total_time_in_us);
    return 0;
}