#include #include #include #include #include "random.hpp" #include "memory/resource.hpp" #include "test.h" namespace { class Unit : public TestSuite { Q_OBJECT const char* name() const { return "test_mem"; } private slots: void initTestCase(); void cleanupTestCase(); void test_alloc(); } unit__; #include "test_mem.moc" constexpr int DataMin = sizeof(void*); constexpr int DataMax = sizeof(void*) * 16; constexpr int LoopCount = 1000000; std::vector sizes__; template struct alloc_ix_t { static std::vector ix_[2]; static bool inited_; }; template std::vector alloc_ix_t::ix_[2] = { std::vector(LoopCount), std::vector(LoopCount) }; template bool alloc_ix_t::inited_ = false; struct alloc_random : alloc_ix_t { alloc_random() { if (inited_) return; inited_ = true; capo::random<> rdm_index(0, LoopCount - 1); for (int i = 0; i < LoopCount; ++i) { ix_[0][static_cast(i)] = ix_[1][static_cast(i)] = rdm_index(); } } }; struct alloc_LIFO : alloc_ix_t { alloc_LIFO() { if (inited_) return; inited_ = true; for (int i = 0, n = LoopCount - 1; i < LoopCount; ++i, --n) { ix_[0][static_cast(i)] = ix_[1][static_cast(n)] = i; } } }; struct alloc_FIFO : alloc_ix_t { alloc_FIFO() { if (inited_) return; inited_ = true; for (int i = 0; i < LoopCount; ++i) { ix_[0][static_cast(i)] = ix_[1][static_cast(i)] = i; } } }; void Unit::initTestCase() { TestSuite::initTestCase(); capo::random<> rdm { DataMin, DataMax }; for (int i = 0; i < LoopCount; ++i) { sizes__.emplace_back(static_cast(rdm())); } } void Unit::cleanupTestCase() { sizes__.clear(); } template void benchmark_alloc() { std::cout << std::endl << "[Threads: " << ThreadsN << ", Mode: " << type_name() << "] " << type_name() << std::endl; std::vector ptrs[ThreadsN]; for (auto& vec : ptrs) { vec.resize(LoopCount); } ModeT mode; std::atomic_int fini { 0 }; test_stopwatch sw; std::thread works[ThreadsN]; int pid = 0; for (auto& w : works) { w = std::thread {[&, pid] { sw.start(); for (std::size_t x = 0; x < 2; ++x) { for(std::size_t n = 0; n < LoopCount; ++n) { int m = mode.ix_[x][n]; void* (& p) = ptrs[pid][static_cast(m)]; std::size_t s = sizes__[static_cast(m)]; if (p == nullptr) { p = AllocT::alloc(s); } else { AllocT::free(p, s); p = nullptr; } } } if (++fini == ThreadsN) { sw.print_elapsed<1>(DataMin, DataMax, LoopCount); } }}; ++pid; } sw.start(); for (auto& w : works) w.join(); } template struct test_performance { static void start() { test_performance::start(); benchmark_alloc(); } }; template struct test_performance { static void start() { benchmark_alloc(); } }; void Unit::test_alloc() { // malloc test_performance::start(); test_performance::start(); test_performance::start(); // pool-alloc test_performance::start(); test_performance::start(); test_performance::start(); } } // internal-linkage