print spent time & performance

This commit is contained in:
mutouyun 2018-11-21 21:38:29 +08:00
parent de39be3c4f
commit 7718a63b24
3 changed files with 125 additions and 13 deletions

View File

@ -62,10 +62,7 @@ public:
auto st = begin() + id(cr_.load(std::memory_order_relaxed)); auto st = begin() + id(cr_.load(std::memory_order_relaxed));
do { do {
// check remain count of consumers // check remain count of consumers
if (st->head_.load(std::memory_order_acquire)) { if (!st->head_.load(std::memory_order_acquire)) {
std::this_thread::yield();
}
else {
st->head_.store(conn_count()); st->head_.store(conn_count());
break; break;
} }

109
test/stopwatch.hpp Normal file
View File

@ -0,0 +1,109 @@
/*
The Capo Library
Code covered by the MIT License
Author: mutouyun (http://orzz.org)
*/
#pragma once
#include <chrono> // std::chrono
#include <array> // std::array
#include <utility> // std::pair, std::declval
#include <cstddef> // size_t
namespace capo {
////////////////////////////////////////////////////////////////
/// Stopwatch - can store multiple sets of time
////////////////////////////////////////////////////////////////
template <size_t CountN = 1, class ClockT = std::chrono::steady_clock>
class stopwatch : public ClockT
{
using base_t = ClockT;
static_assert(CountN > 0, "The count must be greater than 0");
public:
using rep = typename ClockT::rep;
using period = typename ClockT::period;
using duration = typename ClockT::duration;
using time_point = typename ClockT::time_point;
private:
using pair_t = std::pair<time_point/*start*/, time_point/*paused*/>;
std::array<pair_t, CountN> points_;
bool is_stopped_ = true;
public:
stopwatch(bool start_watch = false)
{
if (start_watch) start();
}
public:
bool is_stopped(void) const
{
return is_stopped_;
}
template <size_t N = 0>
bool is_paused(void) const
{
return (points_[N].second != points_[N].first);
}
template <size_t N = 0>
duration elapsed(void)
{
if (is_stopped())
return duration::zero();
else
if (is_paused<N>())
return (points_[N].second - points_[N].first);
else
return ClockT::now() - points_[N].first;
}
template <typename ToDur, size_t N = 0>
auto elapsed(void) -> decltype(std::declval<ToDur>().count())
{
return std::chrono::duration_cast<ToDur>(elapsed<N>()).count();
}
template <size_t N = 0>
void pause(void)
{
points_[N].second = ClockT::now();
}
template <size_t N = 0>
void restart(void)
{
points_[N].second = points_[N].first =
ClockT::now() - (points_[N].second - points_[N].first);
}
void start(void)
{
time_point now = ClockT::now();
for (auto& pt : points_)
{
pt.second = pt.first = now - (pt.second - pt.first);
}
is_stopped_ = false;
}
void stop(void)
{
for (auto& pt : points_)
{
pt.second = pt.first;
}
is_stopped_ = true;
}
};
} // namespace capo

View File

@ -2,9 +2,11 @@
#include <string> #include <string>
#include <type_traits> #include <type_traits>
#include <memory> #include <memory>
#include <new>
#include "circ_queue.h" #include "circ_queue.h"
#include "test.h" #include "test.h"
#include "stopwatch.hpp"
namespace { namespace {
@ -32,8 +34,8 @@ void Unit::test_inst(void) {
} }
void Unit::test_producer(void) { void Unit::test_producer(void) {
cq__ = new cq_t; ::new (cq__) cq_t;
std::thread consumers[3]; std::thread consumers[1];
for (auto& c : consumers) { for (auto& c : consumers) {
c = std::thread{[&c] { c = std::thread{[&c] {
@ -48,11 +50,8 @@ void Unit::test_producer(void) {
do { do {
while (cur != cq__->cursor()) { while (cur != cq__->cursor()) {
int d = *static_cast<const int*>(cq__->get(cur)); int d = *static_cast<const int*>(cq__->get(cur));
// std::cout << &c << ": cur = " << (int)cur << ", " << d << std::endl; if (d < 0) return;
if (d < 0) { QCOMPARE(d, i);
return;
}
else QCOMPARE(d, i);
++cur; ++cur;
++i; ++i;
} }
@ -63,20 +62,27 @@ void Unit::test_producer(void) {
while (cq__->conn_count() != std::extent<decltype(consumers)>::value) { while (cq__->conn_count() != std::extent<decltype(consumers)>::value) {
std::this_thread::yield(); std::this_thread::yield();
} }
capo::stopwatch<> sw;
constexpr static int loops = 1000000;
std::cout << "start producer..." << std::endl; std::cout << "start producer..." << std::endl;
for (int i = 0; i < 1000; ++i) { sw.start();
for (int i = 0; i < loops; ++i) {
auto d = static_cast<int*>(cq__->acquire()); auto d = static_cast<int*>(cq__->acquire());
*d = i; *d = i;
cq__->commit(); cq__->commit();
} }
auto d = static_cast<int*>(cq__->acquire()); auto d = static_cast<int*>(cq__->acquire());
*d = -1; *d = -1;
std::cout << "put: quit..." << std::endl;
cq__->commit(); cq__->commit();
for (auto& c : consumers) { for (auto& c : consumers) {
c.join(); c.join();
} }
auto ts = sw.elapsed<std::chrono::microseconds>();
std::cout << "time spent : " << (ts / 1000) << " ms" << std::endl;
std::cout << "performance: " << (double(ts) / double(loops)) << " us/msg" << std::endl;
} }
} // internal-linkage } // internal-linkage