mCRL2
Loading...
Searching...
No Matches
benchmark_shared.h
Go to the documentation of this file.
1// Author(s): Maurice Laveaux
2// Copyright: see the accompanying file COPYING or copy at
3// https://github.com/mCRL2org/mCRL2/blob/master/COPYING
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9
10#ifndef MCRL2_ATERMPP_BENCHMARK_BENCHMARK_SHARED_H
11#define MCRL2_ATERMPP_BENCHMARK_BENCHMARK_SHARED_H
12
13#include "mcrl2/atermpp/aterm.h"
14#include "mcrl2/utilities/stopwatch.h"
15
16#include <cassert>
17#include <cstddef>
18#include <thread>
19#include <utility>
20#include <vector>
21
22/// \brief Run the given function f on number_of_threads threads (including the main thread) and
23/// report the elapsed wall-clock time.
24/// \pre number_of_threads >= 1.
25template<typename F>
26void benchmark_threads(std::size_t number_of_threads, F f)
27{
28 assert(number_of_threads >= 1);
29
30 stopwatch timer;
31
32 // Initialize a number of worker threads. std::jthread joins on destruction, which keeps this
33 // exception-safe: if f(0) throws below, the still-running threads are joined during unwinding
34 // instead of triggering std::terminate.
35 std::vector<std::jthread> threads(number_of_threads - 1);
36 std::size_t id = 1;
37 for (auto& thread : threads)
38 {
39 thread = std::jthread(f, id);
40 ++id;
41 }
42
43 // Run the benchmark on the main thread as well.
44 f(0);
45
46 // Wait for all worker threads to complete before reading the timer.
47 for (auto& thread : threads)
48 {
49 thread.join();
50 }
51
52 std::cerr << "time: " << timer.seconds() << std::endl;
53}
54
55/// \brief Create a nested function application f_depth. Where f_0 = c and f_i = f(f_i-1,...,f_i-1).
56template<bool with_converter = false>
57atermpp::aterm create_nested_function(const std::string& function_name, const std::string& leaf_name, std::size_t number_of_arguments, std::size_t depth)
58{
59 // Create a suitable function application.
60 atermpp::function_symbol f(function_name, number_of_arguments);
61 atermpp::function_symbol c(leaf_name, 0);
62
63 atermpp::aterm c_term(c);
64
65 // Initialize a wide function application.
66 std::vector<atermpp::aterm> arguments(f.arity());
67 for (atermpp::aterm& argument: arguments)
68 {
69 argument = c_term;
70 }
71 atermpp::aterm f_term(f, arguments.begin(), arguments.end());
72
73 for (std::size_t j = 0; j < depth; ++j)
74 {
75 // Create a very wide nested function application
76 for (atermpp::aterm& argument: arguments)
77 {
78 argument = f_term;
79 }
80
81 if (with_converter)
82 {
83 make_term_appl(f_term, f, arguments.begin(), arguments.end(), atermpp::detail::do_not_convert_term<atermpp::aterm>());
84 }
85 else
86 {
87 make_term_appl(f_term, f, arguments.begin(), arguments.end());
88 }
89 }
90
91 return f_term;
92}
93
94/// \brief Create a nested function application f_depth. Where f_0 = c and f_i = f(f_i-1,...,f_i-1).
95/// However, this function uses the fixed arity constructor of length N which should be faster.
96template<std::size_t N>
97atermpp::aterm create_nested_function(const std::string& function_name, const std::string& leaf_name, std::size_t depth)
98{
99 // Create a suitable function application.
100 atermpp::function_symbol f(function_name, N);
101 atermpp::function_symbol c(leaf_name, 0);
102
103 atermpp::aterm c_term(c);
104
105 // Construct f(c, ..., c) with exactly N arguments.
106 atermpp::aterm f_term = [&]<std::size_t... I>(std::index_sequence<I...>)
107 {
108 return atermpp::aterm(f, (static_cast<void>(I), c_term)...);
109 }(std::make_index_sequence<N>{});
110
111 for (std::size_t j = 0; j < depth; ++j)
112 {
113 // Construct f(f_term, ..., f_term) with exactly N arguments.
114 [&]<std::size_t... I>(std::index_sequence<I...>)
115 {
116 make_term_appl(f_term, f, (static_cast<void>(I), f_term)...);
117 }(std::make_index_sequence<N>{});
118 }
119
120 return f_term;
121}
122
123#endif // MCRL2_ATERMPP_BENCHMARK_BENCHMARK_SHARED_H
atermpp::aterm create_nested_function(const std::string &function_name, const std::string &leaf_name, std::size_t number_of_arguments, std::size_t depth)
Create a nested function application f_depth. Where f_0 = c and f_i = f(f_i-1,...,...
atermpp::aterm create_nested_function(const std::string &function_name, const std::string &leaf_name, std::size_t depth)
Create a nested function application f_depth. Where f_0 = c and f_i = f(f_i-1,...,...
void benchmark_threads(std::size_t number_of_threads, F f)
Run the given function f on number_of_threads threads (including the main thread) and report the elap...
void enable_garbage_collection(bool enable)
Enable garbage collection when passing true and disable otherwise.
Definition aterm_pool.h:133
A unordered_map class in which aterms can be stored.
Implements a simple stopwatch that starts on construction.
Definition stopwatch.h:17
The main namespace for the aterm++ library.
int main(int argc, char *argv[])