Skip to content

Instantly share code, notes, and snippets.

@gamozolabs
Created July 7, 2019 10:52
Show Gist options
  • Save gamozolabs/ac4bd0f1478a9a2b197a12e6d617f728 to your computer and use it in GitHub Desktop.
Save gamozolabs/ac4bd0f1478a9a2b197a12e6d617f728 to your computer and use it in GitHub Desktop.
4 KiB tmpfs read
use std::sync::atomic::{AtomicUsize, Ordering};
// Usage: Make a 4 KiB file located at /mnt/tmpfstest/test.bin and run the
// tool with `cargo run --release`
/// Runs multiple threads at a time incrementally displaying the syscall
/// throughput of 4-KiB random reads to a `tmpfs` hosted mountpoint
fn benchmark_random_read_scaling() {
for num_threads in 1..=256 {
/// Lock to wait for all threads to spawn
static THREAD_LOCKSTEPPER: AtomicUsize = AtomicUsize::new(0);
/// CPU time spent (in cycles)
static CYCLES: AtomicUsize = AtomicUsize::new(0);
/// Number of file accesses to perform per thread
const NUM_ACCESSES: usize = 4096;
let mut threads = Vec::new();
// Reset lock and performance information
THREAD_LOCKSTEPPER.store(0, Ordering::SeqCst);
CYCLES.store(0, Ordering::SeqCst);
for thr in 0..num_threads {
threads.push(std::thread::spawn(move || {
// Wait for all threads to come online in a busy loop
THREAD_LOCKSTEPPER.fetch_add(1, Ordering::SeqCst);
while THREAD_LOCKSTEPPER
.load(Ordering::SeqCst) != num_threads {}
// Start a "timer" by storing the current CPU cycle count
let start = unsafe { core::arch::x86_64::_rdtsc() };
for _ in 0..NUM_ACCESSES {
assert!(std::fs::read("/mnt/tmpfstest/test.bin")
.unwrap().len() == 4096);
}
// Compute number of CPU cycles for the operation
let elapsed = unsafe { core::arch::x86_64::_rdtsc() - start };
CYCLES.fetch_add(elapsed as usize, Ordering::SeqCst);
}));
}
// Wait for all threads to complete
for thr in threads {
thr.join().unwrap();
}
// Get number of cycles spent by all of the workers
let cycles = CYCLES.load(Ordering::SeqCst);
print!("With {:4} active read threads: {:10.1} cycles/file read\n",
num_threads, cycles as f64 / (num_threads * NUM_ACCESSES) as f64);
}
}
fn main() {
print!("Warning: This is a benchmarking tool, make sure you're using \
--release!\n");
benchmark_random_read_scaling();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment