Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/target
/output
/scripts/output
Cargo.lock
/venv
src/cpp-ring-queues-research/benchmarks.sh
Expand Down
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "queues/moodycamel_cpp/cpp_src/concurrentqueue"]
path = queues/moodycamel_cpp/cpp_src/concurrentqueue
[submodule "data_structures/queues/moodycamel_cpp/cpp_src/concurrentqueue"]
path = data_structures/queues/moodycamel_cpp/cpp_src/concurrentqueue
url = https://github.com/cameron314/concurrentqueue.git
55 changes: 28 additions & 27 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,34 @@
resolver = "2"
members = [
"benchmark_core",
"queues/array_queue",
"queues/atomic_queue",
"queues/basic_queue",
"queues/bbq",
"queues/boost_queue_cpp",
"queues/bounded_concurrent_queue",
"queues/unbounded_concurrent_queue",
"queues/bounded_ringbuffer",
"queues/faaa_queue",
"queues/faaa_queue_cpp",
"queues/lcrq_cpp",
"queues/lcrq",
"queues/lprq_cpp",
"queues/lprq",
"queues/lf_queue",
"queues/lockfree_queue",
"stacks/lockfree_stack",
"queues/moodycamel_cpp",
"queues/ms_queue",
"queues/scc_queue",
"stacks/scc_stack",
"queues/scc2_queue",
"stacks/scc2_stack",
"queues/seg_queue",
"queues/tz_queue_leak",
"queues/tz_queue_hp",
"queues/wf_queue",
"data_structures/queues/array_queue",
"data_structures/queues/atomic_queue",
"data_structures/queues/basic_queue",
"data_structures/queues/bbq",
"data_structures/queues/boost_queue_cpp",
"data_structures/queues/bounded_concurrent_queue",
"data_structures/queues/unbounded_concurrent_queue",
"data_structures/queues/bounded_ringbuffer",
"data_structures/queues/faaa_queue",
"data_structures/queues/faaa_queue_cpp",
"data_structures/queues/lcrq_cpp",
"data_structures/queues/lcrq",
"data_structures/queues/lprq_cpp",
"data_structures/queues/lprq",
"data_structures/queues/lf_queue",
"data_structures/queues/lockfree_queue",
"data_structures/stacks/lockfree_stack",
"data_structures/queues/moodycamel_cpp",
"data_structures/queues/ms_queue",
"data_structures/queues/scc_queue",
"data_structures/stacks/scc_stack",
"data_structures/queues/scc2_queue",
"data_structures/stacks/scc2_stack",
"data_structures/queues/seg_queue",
"data_structures/queues/tz_queue_leak",
"data_structures/queues/tz_queue_hp",
"data_structures/queues/wf_queue",
"data_structures/priority_queues/basic_priority_queue",
]

[workspace.dependencies]
Expand Down
121 changes: 88 additions & 33 deletions benchmark_core/src/arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,12 @@ pub struct Args {
/// Duration of each benchmark
#[arg(short, long, default_value_t = 10)]
pub time_limit: u64,
/// Attemps to only use on socket. Specific for the developers test environment.
/// Attemps to only use one socket. Specific for the developers test environment.
#[arg(short, long, default_value_t = true, action = ArgAction::SetFalse)]
pub one_socket: bool,
/// How many times the chosen benchmark should be run.
#[arg(short, long, default_value_t = 1)]
pub iterations: u32,
/// Count empty pop operations. Off by default.
#[arg(short, long, default_value_t = false)]
pub empty_pops: bool,
/// Set the size of the bounded queues.
#[arg(short, long, default_value_t = 10000)]
pub queue_size: u32,
/// Set the amount of floating point numbers generated between each operation. Default is 10.
#[arg(short, long, default_value_t = 10)]
pub delay: u64,
Expand All @@ -27,11 +21,11 @@ pub struct Args {
pub path_output: String,
/// Choose which benchmark to run.
#[command(subcommand)]
pub benchmark: Benchmarks,
pub benchmark: BenchmarkTypes,
Comment thread
emilbjornlinger marked this conversation as resolved.
Outdated
/// If set to true, benchmark will output to stdout instead of to files.
#[arg(long = "write-stdout", default_value_t = false)]
pub write_to_stdout: bool,
/// Prefill the queue with values before running the benchmark.
/// Prefill the data structure with values before running the benchmark.
#[arg(short, long, default_value_t = 0)]
pub prefill_amount: u64,
/// Write benchmark configuration and hardware info to a separate file.
Expand All @@ -45,27 +39,49 @@ pub struct Args {

/// Possible benchmark types.
#[derive(Subcommand, Debug)]
pub enum Benchmarks {
pub enum BenchmarkTypes {
Queue(QueueArgs),
PriorityQueue(PriorityQueueArgs),
}

/// Arguments for the Queue benchmark type
#[derive(ClapArgs, Debug, Clone)]
pub struct QueueArgs {
/// Count empty pop operations. Off by default.
#[arg(short, long, default_value_t = false)]
pub empty_pops: bool,
/// Set the size of the bounded queues.
#[arg(short, long, default_value_t = 10000)]
pub queue_size: u32,
/// The runner to use for the benchmark
#[command(subcommand)]
pub benchmark_runner: QueueBenchmarks,
}

/// Benchmark runners for queues.
#[derive(Subcommand, Debug, Clone)]
pub enum QueueBenchmarks {
/// ProdCon throughput test. Decide amount of producers and consumers using flags.
ProdCon(ProdConArgs),
ProdCon(QueueProdConArgs),
/// A test where each thread performs both consume and produce based on a random floating point
/// value. Spread is decided using the `--spread` flag.
EnqDeq(EnqDeqArgs),
EnqDeqPairs(EnqDeqPairsArgs),
BFS(BFSArgs),
EnqDeq(QueueEnqDeqArgs),
EnqDeqPairs(QueueEnqDeqPairsArgs),
BFS(QueueBFSArgs),
}

#[derive(ClapArgs, Debug)]
pub struct ProdConArgs {
#[derive(ClapArgs, Debug, Clone)]
pub struct QueueProdConArgs {
/// Amount of producers to be used for basic throughput test.
#[arg(short, long, default_value_t = 20)]
pub producers: usize,
/// Amount of consumers to be used for basic throughput test.
#[arg(short, long, default_value_t = 20)]
pub consumers: usize,
}
#[derive(ClapArgs, Debug)]
pub struct EnqDeqArgs {

#[derive(ClapArgs, Debug, Clone)]
pub struct QueueEnqDeqArgs {
/// Set the thread count for the pingpong benchmark.
#[arg(long = "thread-count", default_value_t = 20)]
pub thread_count: usize,
Expand All @@ -74,31 +90,62 @@ pub struct EnqDeqArgs {
#[arg(long = "spread", default_value_t = 0.5)]
pub spread: f64,
}
#[derive(ClapArgs, Debug)]
pub struct EnqDeqPairsArgs {

#[derive(ClapArgs, Debug, Clone)]
pub struct QueueEnqDeqPairsArgs {
/// Set the thread count for the pingpong benchmark.
#[arg(long = "thread-count", default_value_t = 20)]
pub thread_count: usize,
}
#[derive(ClapArgs, Debug)]
pub struct BFSArgs {

#[derive(ClapArgs, Debug, Clone)]
pub struct QueueBFSArgs {
#[arg(short, long, default_value_t = 20)]
pub thread_count: usize,
#[arg(short, long)]
pub graph_file: String,
#[arg(short, long, default_value_t = false)]
pub no_verify: bool,
}

/// Arguments for the PriorityQueue benchmark type
#[derive(ClapArgs, Debug, Clone)]
pub struct PriorityQueueArgs {
/// Set the size of the bounded queues.
#[arg(short, long, default_value_t = 10000)]
pub queue_size: u32,
/// The runner to use for the benchmark
#[command(subcommand)]
pub benchmark_runner: PriorityQueueBenchmarks,
}

/// Benchmark runners for priority queues.
#[derive(Subcommand, Debug, Clone)]
pub enum PriorityQueueBenchmarks {
/// Producer Consumer throughput test. Decide amount of producers and consumers using flags.
ProdCon(PQProdConArgs),
}

#[derive(ClapArgs, Debug, Clone)]
pub struct PQProdConArgs {
/// Amount of producers to be used for basic throughput test.
#[arg(short, long, default_value_t = 20)]
pub producers: usize,
/// Amount of consumers to be used for basic throughput test.
#[arg(short, long, default_value_t = 20)]
pub consumers: usize,
}

/// This is used to write the benchmark type to the output.
/// That is why the arguments are discarded.
impl Display for Benchmarks {
impl Display for QueueBenchmarks {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Benchmarks::ProdCon(_) => write!(f, "ProdCon"),
Benchmarks::EnqDeq(_) => write!(f, "EnqDeq"),
Benchmarks::EnqDeqPairs(_) => write!(f, "EnqDeqPairs"),
QueueBenchmarks::ProdCon(_) => write!(f, "ProdCon"),
QueueBenchmarks::EnqDeq(_) => write!(f, "EnqDeq"),
QueueBenchmarks::EnqDeqPairs(_) => write!(f, "EnqDeqPairs"),
// #[cfg(feature = "bfs")]
Benchmarks::BFS(_) => write!(f, "BFS"),
QueueBenchmarks::BFS(_) => write!(f, "BFS"),
}
}
}
Expand All @@ -108,7 +155,6 @@ impl Display for Args {
writeln!(f, "Time limit: {}", self.time_limit)?;
writeln!(f, "One socket?: {}", self.one_socket)?;
writeln!(f, "Iterations: {}", self.iterations)?;
writeln!(f, "Queue size: {}", self.queue_size)?;
writeln!(f, "Delay: {}", self.delay)?;
writeln!(f, "Output path: {}", self.path_output)?;
writeln!(f, "Benchmark: {:?}", self.benchmark)?;
Expand All @@ -118,6 +164,13 @@ impl Display for Args {
}
}

impl Display for BenchmarkTypes {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "Benchmark type: {:?}", self)?;
Ok(())
}
}

/// Implemented so that tests are easier to write.
impl Default for Args {
fn default() -> Self {
Expand All @@ -126,13 +179,15 @@ impl Default for Args {
time_limit: 1,
one_socket: true,
iterations: 1,
empty_pops: false,
queue_size: 10000,
delay: 10,
path_output: "".to_string(),
benchmark: Benchmarks::ProdCon(ProdConArgs {
producers: 5,
consumers: 5,
benchmark: BenchmarkTypes::Queue(QueueArgs {
empty_pops: false,
queue_size: 10000,
benchmark_runner: QueueBenchmarks::ProdCon(QueueProdConArgs {
producers: 5,
consumers: 5,
}),
}),
write_to_stdout: true,
print_info: false,
Expand Down
Loading
Loading