From d18a3b15a7f2201fc6e175f5a23d2426c4cea5c7 Mon Sep 17 00:00:00 2001 From: "Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com)" Date: Tue, 23 Feb 2021 12:58:10 +0000 Subject: Begin dynamic_thread_pool_group benchmark program. --- .../v2.0/detail/impl/dynamic_thread_pool_group.ipp | 4 +- include/llfio/v2.0/detail/impl/posix/statfs.ipp | 1 + programs/CMakeLists.txt | 7 +- programs/benchmark-async/main.cpp | 4 +- .../benchmark-dynamic_thread_pool_group/main.cpp | 177 +++++++++++++++++++++ 5 files changed, 186 insertions(+), 7 deletions(-) create mode 100644 programs/benchmark-dynamic_thread_pool_group/main.cpp diff --git a/include/llfio/v2.0/detail/impl/dynamic_thread_pool_group.ipp b/include/llfio/v2.0/detail/impl/dynamic_thread_pool_group.ipp index df10efcb..8d54c52a 100644 --- a/include/llfio/v2.0/detail/impl/dynamic_thread_pool_group.ipp +++ b/include/llfio/v2.0/detail/impl/dynamic_thread_pool_group.ipp @@ -1893,7 +1893,7 @@ namespace detail if(workitem->_timepoint1 - now > std::chrono::seconds(0)) { // Timer fired short, so schedule it again - _submit_work_item(g, workitem, false); + _submit_work_item(g, true, false, workitem, false); return; } #endif @@ -1906,7 +1906,7 @@ namespace detail if(workitem->_timepoint2 - now > std::chrono::seconds(0)) { // Timer fired short, so schedule it again - _submit_work_item(g, workitem, false); + _submit_work_item(g, true, false, workitem, false); return; } #endif diff --git a/include/llfio/v2.0/detail/impl/posix/statfs.ipp b/include/llfio/v2.0/detail/impl/posix/statfs.ipp index c8455ef6..2e3b0859 100644 --- a/include/llfio/v2.0/detail/impl/posix/statfs.ipp +++ b/include/llfio/v2.0/detail/impl/posix/statfs.ipp @@ -340,6 +340,7 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result statfs_t::fill(const handle &h, s LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result> statfs_t::_fill_ios(const handle &h, const std::string & /*unused*/) noexcept { + (void) h; try { #ifdef __linux__ diff --git a/programs/CMakeLists.txt b/programs/CMakeLists.txt index 07db5753..ad4bb919 100644 --- a/programs/CMakeLists.txt +++ b/programs/CMakeLists.txt @@ -11,8 +11,7 @@ find_quickcpplib_library(quickcpplib ) find_quickcpplib_library(outcome GIT_REPOSITORY "https://github.com/ned14/outcome.git" -# GIT_TAG "develop" - GIT_TAG "better_optimisation" ## future Outcome v2.2 + GIT_TAG "master" REQUIRED IS_HEADER_ONLY ) @@ -48,13 +47,15 @@ function(make_program program) endfunction() make_program(benchmark-async llfio::hl) +make_program(benchmark-dynamic_thread_pool_group llfio::hl) make_program(benchmark-iostreams llfio::hl) make_program(benchmark-locking llfio::hl kerneltest::hl) make_program(fs-probe llfio::hl) make_program(illegal-codepoints llfio::hl) make_program(key-value-store llfio::hl) -target_include_directories(benchmark-async PRIVATE "benchmark-async/asio/asio/include") +target_include_directories(benchmark-async PRIVATE "asio/asio/include") +target_include_directories(benchmark-dynamic_thread_pool_group PRIVATE "asio/asio/include") if(MSVC) target_compile_options(illegal-codepoints PUBLIC /utf-8) diff --git a/programs/benchmark-async/main.cpp b/programs/benchmark-async/main.cpp index 1213dd4f..613f338d 100644 --- a/programs/benchmark-async/main.cpp +++ b/programs/benchmark-async/main.cpp @@ -377,13 +377,13 @@ completion i/o min 1300 max 1.40714e+06 mean 23037 stddev 15035.4 #include #include -#if __has_include("asio/asio/include/asio.hpp") +#if __has_include("../asio/asio/include/asio.hpp") #define ENABLE_ASIO 1 #if defined(__clang__) && defined(_MSC_VER) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmicrosoft-include" #endif -#include "asio/asio/include/asio.hpp" +#include "../asio/asio/include/asio.hpp" #if defined(__clang__) && defined(_MSC_VER) #pragma clang diagnostic pop #endif diff --git a/programs/benchmark-dynamic_thread_pool_group/main.cpp b/programs/benchmark-dynamic_thread_pool_group/main.cpp new file mode 100644 index 00000000..d5a9cd31 --- /dev/null +++ b/programs/benchmark-dynamic_thread_pool_group/main.cpp @@ -0,0 +1,177 @@ +/* Test the performance of dynamic thread pool group +(C) 2021 Niall Douglas (6 commits) +File Created: Feb 2021 + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License in the accompanying file +Licence.txt or at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + + +Distributed under the Boost Software License, Version 1.0. + (See accompanying file Licence.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +//! Seconds to run the benchmark +static constexpr unsigned BENCHMARK_DURATION = 3; +//! Maximum work items to create +static constexpr unsigned MAX_WORK_ITEMS = 1024; + +#include "../../include/llfio/llfio.hpp" + +#include "quickcpplib/algorithm/small_prng.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +#if __has_include("../asio/asio/include/asio.hpp") +#define ENABLE_ASIO 1 +#if defined(__clang__) && defined(_MSC_VER) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmicrosoft-include" +#endif +#include "../asio/asio/include/asio.hpp" +#if defined(__clang__) && defined(_MSC_VER) +#pragma clang diagnostic pop +#endif +#endif + +namespace llfio = LLFIO_V2_NAMESPACE; + +struct asio_runner +{ + std::atomic cancel{false}; + asio::io_context ctx; + + template struct C + { + asio_runner *parent; + F f; + C(asio_runner *_parent, F &&_f) + : parent(_parent) + , f(std::move(_f)) + { + } + void operator()() const + { + f(); + if(!parent->cancel.load(std::memory_order_relaxed)) + { + parent->ctx.post(*this); + } + } + }; + template void add_workitem(F &&f) { ctx.post(C(this, std::move(f))); } + void run(unsigned seconds) + { + std::vector threads; + for(size_t n = 0; n < std::thread::hardware_concurrency(); n++) + { + threads.emplace_back([&] { ctx.run(); }); + } + std::this_thread::sleep_for(std::chrono::seconds(seconds)); + cancel.store(true, std::memory_order_release); + for(auto &i : threads) + { + i.join(); + } + } +}; + +template void benchmark(const char *name) +{ + std::cout << "Benchmarking " << name << " ..." << std::endl; + struct shared_t + { + std::atomic concurrency{0}; + std::atomic max_concurrency{0}; + }; + struct worker + { + shared_t *shared; + char buffer[4096]; + QUICKCPPLIB_NAMESPACE::algorithm::hash::sha256_hash::result_type hash; + uint64_t count{0}; + + void operator()() + { + auto concurrency = shared->concurrency.fetch_add(1, std::memory_order_relaxed) + 1; + if(concurrency > shared->max_concurrency.load(std::memory_order_relaxed)) + { + shared->max_concurrency.store(concurrency, std::memory_order_relaxed); + } + hash = QUICKCPPLIB_NAMESPACE::algorithm::hash::sha256_hash::hash(buffer, sizeof(buffer)); + count++; + shared->concurrency.fetch_sub(1, std::memory_order_relaxed); + } + explicit worker(shared_t *_shared) + : shared(_shared) + { + } + }; + std::vector workers; + std::vector> results; + QUICKCPPLIB_NAMESPACE::algorithm::small_prng::small_prng rand; + for(size_t items = 1; items <= MAX_WORK_ITEMS; items <<= 1) + { + shared_t shared; + workers.clear(); + for(size_t n = 0; n < items; n++) + { + workers.emplace_back(&shared); + for(size_t i = 0; i < sizeof(worker::buffer); i += 4) + { + auto *p = (uint32_t *) (workers.back().buffer + i); + *p = rand(); + } + } + Runner runner; + for(auto &i : workers) + { + runner.add_workitem([&] { i(); }); + } + auto begin = std::chrono::steady_clock::now(); + runner.run(BENCHMARK_DURATION); + auto end = std::chrono::steady_clock::now(); + uint64_t total = 0; + for(auto &i : workers) + { + total += i.count; + } + results.emplace_back(items, 1000000.0 * total / std::chrono::duration_cast(end - begin).count(), shared.max_concurrency); + std::cout << " For " << std::get<0>(results.back()) << " work items got " << std::get<1>(results.back()) << " SHA256 hashes/sec with " + << std::get<2>(results.back()) << " maximum concurrency." << std::endl; + } + std::ofstream out(std::string(name) + "_results.csv"); + out << R"("Work items","SHA256 hashes/sec","Max concurrency")"; + for(auto &i : results) + { + out << "\n" << std::get<0>(i) << "," << std::get<1>(i) << "," << std::get<2>(i); + } + out << std::endl; +} + +int main(void) +{ +#if ENABLE_ASIO + benchmark("asio"); +#endif + + return 0; +} \ No newline at end of file -- cgit v1.2.3