aboutsummaryrefslogtreecommitdiff
path: root/tests/performance_tests/performance_tests.h
diff options
context:
space:
mode:
authorAntonio Juarez <antonio.maria.juarez@live.com>2014-03-03 22:07:58 +0000
committerAntonio Juarez <antonio.maria.juarez@live.com>2014-03-03 22:07:58 +0000
commit296ae46ed8f8f6e5f986f978febad302e3df231a (patch)
tree1629164454a239308f33c9e12afb22e7f3cd8eeb /tests/performance_tests/performance_tests.h
parentchanged name (diff)
downloadmonero-296ae46ed8f8f6e5f986f978febad302e3df231a.tar.xz
moved all stuff to github
Diffstat (limited to 'tests/performance_tests/performance_tests.h')
-rw-r--r--tests/performance_tests/performance_tests.h118
1 files changed, 118 insertions, 0 deletions
diff --git a/tests/performance_tests/performance_tests.h b/tests/performance_tests/performance_tests.h
new file mode 100644
index 000000000..c7efe93f1
--- /dev/null
+++ b/tests/performance_tests/performance_tests.h
@@ -0,0 +1,118 @@
+// Copyright (c) 2012-2013 The Cryptonote developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#pragma once
+
+#include <iostream>
+#include <stdint.h>
+
+#include <boost/chrono.hpp>
+
+class performance_timer
+{
+public:
+ typedef boost::chrono::high_resolution_clock clock;
+
+ performance_timer()
+ {
+ m_base = clock::now();
+ }
+
+ void start()
+ {
+ m_start = clock::now();
+ }
+
+ int elapsed_ms()
+ {
+ clock::duration elapsed = clock::now() - m_start;
+ return static_cast<int>(boost::chrono::duration_cast<boost::chrono::milliseconds>(elapsed).count());
+ }
+
+private:
+ clock::time_point m_base;
+ clock::time_point m_start;
+};
+
+
+template <typename T>
+class test_runner
+{
+public:
+ test_runner()
+ : m_elapsed(0)
+ {
+ }
+
+ bool run()
+ {
+ T test;
+ if (!test.init())
+ return false;
+
+ performance_timer timer;
+ timer.start();
+ warm_up();
+ std::cout << "Warm up: " << timer.elapsed_ms() << " ms" << std::endl;
+
+ timer.start();
+ for (size_t i = 0; i < T::loop_count; ++i)
+ {
+ if (!test.test())
+ return false;
+ }
+ m_elapsed = timer.elapsed_ms();
+
+ return true;
+ }
+
+ int elapsed_time() const { return m_elapsed; }
+
+ int time_per_call() const
+ {
+ static_assert(0 < T::loop_count, "T::loop_count must be greater than 0");
+ return m_elapsed / T::loop_count;
+ }
+
+private:
+ /**
+ * Warm up processor core, enabling turbo boost, etc.
+ */
+ uint64_t warm_up()
+ {
+ const size_t warm_up_rounds = 1000 * 1000 * 1000;
+ m_warm_up = 0;
+ for (size_t i = 0; i < warm_up_rounds; ++i)
+ {
+ ++m_warm_up;
+ }
+ return m_warm_up;
+ }
+
+private:
+ volatile uint64_t m_warm_up; ///<! This field is intended for preclude compiler optimizations
+ int m_elapsed;
+};
+
+template <typename T>
+void run_test(const char* test_name)
+{
+ test_runner<T> runner;
+ if (runner.run())
+ {
+ std::cout << test_name << " - OK:\n";
+ std::cout << " loop count: " << T::loop_count << '\n';
+ std::cout << " elapsed: " << runner.elapsed_time() << " ms\n";
+ std::cout << " time per call: " << runner.time_per_call() << " ms/call\n" << std::endl;
+ }
+ else
+ {
+ std::cout << test_name << " - FAILED" << std::endl;
+ }
+}
+
+#define QUOTEME(x) #x
+#define TEST_PERFORMANCE0(test_class) run_test< test_class >(QUOTEME(test_class))
+#define TEST_PERFORMANCE1(test_class, a0) run_test< test_class<a0> >(QUOTEME(test_class<a0>))
+#define TEST_PERFORMANCE2(test_class, a0, a1) run_test< test_class<a0, a1> >(QUOTEME(test_class) "<" QUOTEME(a0) ", " QUOTEME(a1) ">")