Skip to content

Instantly share code, notes, and snippets.

@linsinan1995
Last active January 7, 2021 23:19
Show Gist options
  • Save linsinan1995/c4a96bfc1da91cb61847995c5697a274 to your computer and use it in GitHub Desktop.
Save linsinan1995/c4a96bfc1da91cb61847995c5697a274 to your computer and use it in GitHub Desktop.
easy benchmark template and example
// simple framework for timing, feel free to modify it.
#include <chrono>
#include <thread>
#include <iostream>
template <typename Type = std::chrono::milliseconds> class Timer;
template <typename Type = std::chrono::milliseconds> class scope_timer;
using timer_sec_t = Timer<std::chrono::seconds>;
using timer_min_t = Timer<std::chrono::minutes>;
using timer_nano_t = Timer<std::chrono::nanoseconds>;
using timer_micro_t = Timer<std::chrono::microseconds>;
using timer_milli_t = Timer<std::chrono::milliseconds>;
template <typename Type>
class Timer {
std::chrono::time_point<std::chrono::high_resolution_clock> _start, _end;
public:
size_t niter = 1;
size_t total = 0;
std::string name;
std::ostream &m_os;
Timer(std::string name, std::ostream &os = std::cout ) :
name(move(name)),
m_os(os)
{}
Timer(std::string name, size_t iter, std::ostream &os = std::cout ) :
name(move(name)),
niter(iter),
m_os(os)
{}
void start() {
_start = std::chrono::high_resolution_clock::now();
}
void stop() {
_end = std::chrono::high_resolution_clock::now();
total = std::chrono::duration_cast<Type>( _end - _start ).count();
}
void show() {
m_os << "Job <" << name << ">" << " tooks " << (total / niter);
if constexpr (std::is_same<Type, std::chrono::milliseconds>::value != 0)
m_os << " milliseconds to finish!" << std::endl;
else if constexpr (std::is_same<Type, std::chrono::microseconds>::value != 0)
m_os << " microseconds to finish!" << std::endl;
else if constexpr (std::is_same<Type, std::chrono::seconds>::value != 0)
m_os << " seconds to finish!" << std::endl;
else if constexpr (std::is_same<Type, std::chrono::nanoseconds>::value != 0)
m_os << " nanoseconds to finish!" << std::endl;
else if constexpr (std::is_same<Type, std::chrono::minutes>::value != 0)
m_os << " minutes to finish!" << std::endl;
}
};
template <typename Type>
class scope_timer {
Timer<Type> _t;
public:
template <typename ...Args>
scope_timer(Args &&...args) : _t(std::forward<Args...> (args...) ) { _t.start(); }
~scope_timer() { _t.stop(); _t.show(); }
};
// use case
#include <thread>
#include <vector>
#include <functional>
#include <numeric>
#include <algorithm>
#include <cassert>
#include "benchmark.h"
using namespace std;
using namespace chrono;
using namespace std::chrono_literals; // c++ 14
inline void compute(vector<int> &v, int l, int r) {
while (l < r) { v[l] = l; l ++; }
}
void p_iota(vector<int> &v, int l , int r, int ncore) {
vector<thread> thread_lists;
int n = r / ncore;
for (int i = 0; i < ncore; i ++) {
if (i == ncore - 1) thread_lists.push_back(thread(compute, ref(v), i * n, r));
else thread_lists.push_back(thread(compute, ref(v), i * n, (i + 1) * n));
}
for_each(thread_lists.begin(), thread_lists.end(), mem_fn(&thread::join));
}
// using timer_micro = Timer<microseconds>;
int main () {
vector<int> test_cases { 100000, 1000000, 10000000, 100000000 };
// or
// instead of scope_timer, you can directly use Timer class, but you
// need manually call member function Timer::stop().
cout << "=======================loop=====================\n" << flush;
for (auto n : test_cases) {
vector<int> v (n);
scope_timer t("loop-" + to_string(n));
for (int i = 0; i < n; i++) { v[i] = i; }
}
cout << "\n=====================std::iota==================\n" << flush;
for (auto n : test_cases) {
vector<int> v (n);
scope_timer t("iota-" + to_string(n));
iota(v.begin(), v.end(), 0);
}
cout << "\n=====================p_iota==================\n" << flush;
for (auto n : test_cases) {
vector<int> v (n);
scope_timer t("p_iota-" + to_string(n));
p_iota(v, 0, n, thread::hardware_concurrency());
}
cout << "\n===================valid test==================\n" << flush;
for (auto n : test_cases) {
vector<int> v (n), v1(n), v2(n);
// assign
p_iota(v, 0, n, thread::hardware_concurrency());
iota(v1.begin(), v1.end(), 0);
for (int i = 0; i < n; i++) { v2[i] = i; }
// assign end
for (int i = 0; i < n; i++ ) { assert( v[i] == v1[i] && v1[i] == v2[i] ); }
}
cout << "Valid test passed!\n" << flush;
}
# read filename
filename=p_iota.cpp
g++ -std=c++17 -O2 $filename -fext-numeric-literals -pthread -o test
./test
rm test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment