|
1 | 1 | use clap::{ArgAction, Args as ClapArgs, Parser, Subcommand}; |
2 | 2 | use std::fmt::Display; |
3 | 3 |
|
4 | | -#[derive(Parser, Debug)] |
5 | | -#[command(version, about, long_about = None)] |
6 | | -pub struct Args { |
| 4 | +/// General arguments for all benchmarks |
| 5 | +#[derive(ClapArgs, Debug, Clone)] |
| 6 | +pub struct GeneralArgs { |
7 | 7 | /// Duration of each benchmark |
8 | 8 | #[arg(short, long, default_value_t = 10)] |
9 | 9 | pub time_limit: u64, |
10 | | - /// Attemps to only use on socket. Specific for the developers test environment. |
| 10 | + |
| 11 | + /// Attemps to only use one socket. Specific for the developers test environment. |
11 | 12 | #[arg(short, long, default_value_t = true, action = ArgAction::SetFalse)] |
12 | 13 | pub one_socket: bool, |
| 14 | + |
13 | 15 | /// How many times the chosen benchmark should be run. |
14 | 16 | #[arg(short, long, default_value_t = 1)] |
15 | 17 | pub iterations: u32, |
16 | | - /// Count empty pop operations. Off by default. |
17 | | - #[arg(short, long, default_value_t = false)] |
18 | | - pub empty_pops: bool, |
19 | | - /// Set the size of the bounded queues. |
20 | | - #[arg(short, long, default_value_t = 10000)] |
21 | | - pub queue_size: u32, |
| 18 | + |
22 | 19 | /// Set the amount of floating point numbers generated between each operation. Default is 10. |
23 | 20 | #[arg(short, long, default_value_t = 10)] |
24 | 21 | pub delay: u64, |
| 22 | + |
25 | 23 | /// Set the output path for the result files. |
26 | 24 | #[arg(long = "path", default_value_t = String::from("./output"))] |
27 | 25 | pub path_output: String, |
28 | | - /// Choose which benchmark to run. |
29 | | - #[command(subcommand)] |
30 | | - pub benchmark: Benchmarks, |
| 26 | + |
31 | 27 | /// If set to true, benchmark will output to stdout instead of to files. |
32 | 28 | #[arg(long = "write-stdout", default_value_t = false)] |
33 | 29 | pub write_to_stdout: bool, |
34 | | - /// Prefill the queue with values before running the benchmark. |
35 | | - #[arg(short, long, default_value_t = 0)] |
36 | | - pub prefill_amount: u64, |
| 30 | + |
37 | 31 | /// Write benchmark configuration and hardware info to a separate file. |
38 | 32 | #[arg(long, default_value_t = false, action = ArgAction::SetTrue)] |
39 | 33 | pub print_info: bool, |
| 34 | + |
40 | 35 | #[cfg(feature = "memory_tracking")] |
41 | 36 | /// The interval of which memory tracking will update [ms]. |
42 | 37 | #[arg(long, default_value_t = 50)] |
43 | 38 | pub memory_tracking_interval: u64, |
44 | 39 | } |
45 | 40 |
|
46 | | -/// Possible benchmark types. |
| 41 | +/// Arguments for the FIFO Queue benchmark types |
| 42 | +#[derive(Parser, Debug)] |
| 43 | +#[command(version, about, long_about = None)] |
| 44 | +pub struct FifoQueueArgs { |
| 45 | + /// Count empty pop operations. Off by default. |
| 46 | + #[arg(short, long, default_value_t = false)] |
| 47 | + pub empty_pops: bool, |
| 48 | + |
| 49 | + /// Set the size of the bounded queues. |
| 50 | + #[arg(short, long, default_value_t = 10000)] |
| 51 | + pub queue_size: u32, |
| 52 | + |
| 53 | + /// The runner to use for the benchmark |
| 54 | + #[command(subcommand)] |
| 55 | + pub benchmark_runner: FifoQueueBenchmarks, |
| 56 | + |
| 57 | + /// Prefill the FIFO Queue with default values before running the benchmark. |
| 58 | + #[arg(short, long, default_value_t = 0)] |
| 59 | + pub prefill_amount: u64, |
| 60 | + |
| 61 | + /// General arguments agnostic to the FIFO Queue |
| 62 | + #[command(flatten)] |
| 63 | + pub general_args: GeneralArgs, |
| 64 | +} |
| 65 | + |
| 66 | +/// Benchmark runners for FIFO Queues. |
47 | 67 | #[derive(Subcommand, Debug)] |
48 | | -pub enum Benchmarks { |
49 | | - /// ProdCon throughput test. Decide amount of producers and consumers using flags. |
50 | | - ProdCon(ProdConArgs), |
51 | | - /// A test where each thread performs both consume and produce based on a random floating point |
52 | | - /// value. Spread is decided using the `--spread` flag. |
53 | | - EnqDeq(EnqDeqArgs), |
54 | | - EnqDeqPairs(EnqDeqPairsArgs), |
55 | | - BFS(BFSArgs), |
| 68 | +pub enum FifoQueueBenchmarks { |
| 69 | + /// A benchmark for measuring throughput using producers and consumers that |
| 70 | + /// are each bound to a thread |
| 71 | + ProdCon(FifoQueueProdConArgs), |
| 72 | + |
| 73 | + /// A benchmark measuring throughput where a thread will switch between |
| 74 | + /// producing and consuming |
| 75 | + EnqDeq(FifoQueueEnqDeqArgs), |
| 76 | + |
| 77 | + /// A benchmark measuring throughput where a thread will enqueue an item |
| 78 | + /// and then immediately dequeue it |
| 79 | + EnqDeqPairs(FifoQueueEnqDeqPairsArgs), |
| 80 | + |
| 81 | + /// Benchmarks how fast the FIFO Queue can complete a breadth-first search |
| 82 | + /// on a graph |
| 83 | + BFS(FifoQueueBFSArgs), |
56 | 84 | } |
57 | 85 |
|
58 | 86 | #[derive(ClapArgs, Debug)] |
59 | | -pub struct ProdConArgs { |
60 | | - /// Amount of producers to be used for basic throughput test. |
| 87 | +pub struct FifoQueueProdConArgs { |
| 88 | + /// Amount of producers to be used |
61 | 89 | #[arg(short, long, default_value_t = 20)] |
62 | 90 | pub producers: usize, |
63 | | - /// Amount of consumers to be used for basic throughput test. |
| 91 | + |
| 92 | + /// Amount of consumers to be used |
64 | 93 | #[arg(short, long, default_value_t = 20)] |
65 | 94 | pub consumers: usize, |
66 | 95 | } |
| 96 | + |
67 | 97 | #[derive(ClapArgs, Debug)] |
68 | | -pub struct EnqDeqArgs { |
| 98 | +pub struct FifoQueueEnqDeqArgs { |
69 | 99 | /// Set the thread count for the pingpong benchmark. |
70 | 100 | #[arg(long = "thread-count", default_value_t = 20)] |
71 | 101 | pub thread_count: usize, |
| 102 | + |
72 | 103 | /// Decide the spread of producers/consumers for the pingpong benchmark. |
73 | 104 | /// Ex. 0.3 means 30% produce 70% consume. |
74 | 105 | #[arg(long = "spread", default_value_t = 0.5)] |
75 | 106 | pub spread: f64, |
76 | 107 | } |
| 108 | + |
77 | 109 | #[derive(ClapArgs, Debug)] |
78 | | -pub struct EnqDeqPairsArgs { |
| 110 | +pub struct FifoQueueEnqDeqPairsArgs { |
79 | 111 | /// Set the thread count for the pingpong benchmark. |
80 | 112 | #[arg(long = "thread-count", default_value_t = 20)] |
81 | 113 | pub thread_count: usize, |
82 | 114 | } |
| 115 | + |
83 | 116 | #[derive(ClapArgs, Debug)] |
84 | | -pub struct BFSArgs { |
| 117 | +pub struct FifoQueueBFSArgs { |
85 | 118 | #[arg(short, long, default_value_t = 20)] |
86 | 119 | pub thread_count: usize, |
| 120 | + |
87 | 121 | #[arg(short, long)] |
88 | 122 | pub graph_file: String, |
| 123 | + |
89 | 124 | #[arg(short, long, default_value_t = false)] |
90 | 125 | pub no_verify: bool, |
91 | 126 | } |
| 127 | + |
| 128 | +/// Arguments for the Priority Queue benchmark types |
| 129 | +#[derive(Parser, Debug)] |
| 130 | +#[command(version, about, long_about = None)] |
| 131 | +pub struct PriorityQueueArgs { |
| 132 | + /// Set the size of the bounded queues. |
| 133 | + #[arg(short, long, default_value_t = 10000)] |
| 134 | + pub queue_size: u32, |
| 135 | + |
| 136 | + /// The runner to use for the benchmark |
| 137 | + #[command(subcommand)] |
| 138 | + pub benchmark_runner: PriorityQueueBenchmarks, |
| 139 | + |
| 140 | + /// Prefill the FIFO Queue with default values before running the benchmark. |
| 141 | + #[arg(short, long, default_value_t = 0)] |
| 142 | + pub prefill_amount: u64, |
| 143 | + |
| 144 | + /// General arguments agnostic to the Priority Queue |
| 145 | + #[command(flatten)] |
| 146 | + pub general_args: GeneralArgs, |
| 147 | +} |
| 148 | + |
| 149 | +/// Benchmark runners for priority queues. |
| 150 | +#[derive(Subcommand, Debug)] |
| 151 | +pub enum PriorityQueueBenchmarks { |
| 152 | + /// A benchmark for measuring throughput using producers and consumers that |
| 153 | + /// are each bound to a thread |
| 154 | + ProdCon(PQProdConArgs), |
| 155 | +} |
| 156 | + |
| 157 | +#[derive(ClapArgs, Debug)] |
| 158 | +pub struct PQProdConArgs { |
| 159 | + /// Amount of producers to be used for basic throughput test. |
| 160 | + #[arg(short, long, default_value_t = 20)] |
| 161 | + pub producers: usize, |
| 162 | + |
| 163 | + /// Amount of consumers to be used for basic throughput test. |
| 164 | + #[arg(short, long, default_value_t = 20)] |
| 165 | + pub consumers: usize, |
| 166 | +} |
| 167 | + |
92 | 168 | /// This is used to write the benchmark type to the output. |
93 | 169 | /// That is why the arguments are discarded. |
94 | | -impl Display for Benchmarks { |
| 170 | +impl Display for FifoQueueBenchmarks { |
95 | 171 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
96 | 172 | match self { |
97 | | - Benchmarks::ProdCon(_) => write!(f, "ProdCon"), |
98 | | - Benchmarks::EnqDeq(_) => write!(f, "EnqDeq"), |
99 | | - Benchmarks::EnqDeqPairs(_) => write!(f, "EnqDeqPairs"), |
| 173 | + FifoQueueBenchmarks::ProdCon(_) => write!(f, "ProdCon"), |
| 174 | + FifoQueueBenchmarks::EnqDeq(_) => write!(f, "EnqDeq"), |
| 175 | + FifoQueueBenchmarks::EnqDeqPairs(_) => write!(f, "EnqDeqPairs"), |
100 | 176 | // #[cfg(feature = "bfs")] |
101 | | - Benchmarks::BFS(_) => write!(f, "BFS"), |
| 177 | + FifoQueueBenchmarks::BFS(_) => write!(f, "BFS"), |
102 | 178 | } |
103 | 179 | } |
104 | 180 | } |
| 181 | + |
| 182 | +/// This is used to write the benchmark type to the output. |
| 183 | +/// That is why the arguments are discarded. |
| 184 | +impl Display for PriorityQueueBenchmarks { |
| 185 | + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| 186 | + match self { |
| 187 | + PriorityQueueBenchmarks::ProdCon(_) => write!(f, "ProdCon"), |
| 188 | + } |
| 189 | + } |
| 190 | +} |
| 191 | + |
105 | 192 | /// This is used in the print_info function. |
106 | | -impl Display for Args { |
| 193 | +impl Display for GeneralArgs { |
107 | 194 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
108 | 195 | writeln!(f, "Time limit: {}", self.time_limit)?; |
109 | 196 | writeln!(f, "One socket?: {}", self.one_socket)?; |
110 | 197 | writeln!(f, "Iterations: {}", self.iterations)?; |
111 | | - writeln!(f, "Queue size: {}", self.queue_size)?; |
112 | 198 | writeln!(f, "Delay: {}", self.delay)?; |
113 | 199 | writeln!(f, "Output path: {}", self.path_output)?; |
114 | | - writeln!(f, "Benchmark: {:?}", self.benchmark)?; |
115 | 200 | writeln!(f, "Write to stdout: {}", self.write_to_stdout)?; |
116 | | - writeln!(f, "prefill amount: {}", self.prefill_amount)?; |
117 | 201 | Ok(()) |
118 | 202 | } |
119 | 203 | } |
120 | 204 |
|
121 | 205 | /// Implemented so that tests are easier to write. |
122 | | -impl Default for Args { |
| 206 | +impl Default for GeneralArgs { |
123 | 207 | fn default() -> Self { |
124 | | - Args { |
125 | | - prefill_amount: 0, |
| 208 | + GeneralArgs { |
126 | 209 | time_limit: 1, |
127 | 210 | one_socket: true, |
128 | 211 | iterations: 1, |
129 | | - empty_pops: false, |
130 | | - queue_size: 10000, |
131 | 212 | delay: 10, |
132 | 213 | path_output: "".to_string(), |
133 | | - benchmark: Benchmarks::ProdCon(ProdConArgs { |
134 | | - producers: 5, |
135 | | - consumers: 5, |
136 | | - }), |
137 | 214 | write_to_stdout: true, |
138 | 215 | print_info: false, |
139 | 216 | #[cfg(feature = "memory_tracking")] |
140 | 217 | memory_tracking_interval: 50, |
141 | 218 | } |
142 | 219 | } |
143 | 220 | } |
| 221 | + |
| 222 | +/// Implemented for easier testing |
| 223 | +impl Default for FifoQueueArgs { |
| 224 | + fn default() -> Self { |
| 225 | + FifoQueueArgs { |
| 226 | + empty_pops: false, |
| 227 | + queue_size: 10000, |
| 228 | + benchmark_runner: FifoQueueBenchmarks::ProdCon( |
| 229 | + FifoQueueProdConArgs { |
| 230 | + producers: 20, |
| 231 | + consumers: 20, |
| 232 | + }, |
| 233 | + ), |
| 234 | + prefill_amount: 1000, |
| 235 | + general_args: GeneralArgs::default(), |
| 236 | + } |
| 237 | + } |
| 238 | +} |
| 239 | + |
| 240 | +/// Implemented for easier testing |
| 241 | +impl Default for PriorityQueueArgs { |
| 242 | + fn default() -> Self { |
| 243 | + PriorityQueueArgs { |
| 244 | + queue_size: 10000, |
| 245 | + benchmark_runner: PriorityQueueBenchmarks::ProdCon( |
| 246 | + PQProdConArgs { |
| 247 | + producers: 20, |
| 248 | + consumers: 20, |
| 249 | + }, |
| 250 | + ), |
| 251 | + prefill_amount: 1000, |
| 252 | + general_args: GeneralArgs::default(), |
| 253 | + } |
| 254 | + } |
| 255 | +} |
0 commit comments