Skip to content

Instantly share code, notes, and snippets.

@mvanotti
Created August 29, 2022 20:32
Show Gist options
  • Save mvanotti/7dcb7988804ad0ab5c8a574425e2bf8b to your computer and use it in GitHub Desktop.
Save mvanotti/7dcb7988804ad0ab5c8a574425e2bf8b to your computer and use it in GitHub Desktop.
Code for testing the behavior of rdrand/rdseed in a given system
use std::arch::asm;
use std::env;
use std::thread;
use std::time::{Duration, Instant};
fn rdrand_count(its: usize) -> (u64, Duration) {
let zero: u64 = 0;
let mut count: u64 = 0;
let now = Instant::now();
for _ in 0..its {
unsafe {
asm!(
"rdrand {tmp}",
"adc {count}, {zero}",
zero = in(reg) zero,
count = inout(reg) count,
tmp = out(reg) _
);
}
}
(count, now.elapsed())
}
fn rdseed_count(its: usize) -> (u64, Duration) {
let zero: u64 = 0;
let mut count: u64 = 0;
let now = Instant::now();
for _ in 0..its {
unsafe {
asm!(
"rdseed {tmp}",
"adc {count}, {zero}",
zero = in(reg) zero,
count = inout(reg) count,
tmp = out(reg) _
);
}
}
(count, now.elapsed())
}
fn parse_flags(args: &Vec<String>) -> (fn(usize) -> (u64, Duration), usize, usize) {
println!("{:?}", args);
// args[1] should have the function name.
let func = if args.len() > 1 {
match &args[1][..] {
"rdseed" => rdseed_count,
"rdrand" => rdrand_count,
_ => {
panic!(
"invalid function {}. usage: {} rdrand/rdseed iterations threads",
args[1], args[0]
);
}
}
} else {
rdseed_count
};
let tries = if args.len() > 2 {
args[2].parse().unwrap()
} else {
4000
};
let num_threads = if args.len() > 3 {
args[3].parse().unwrap()
} else {
2
};
return (func, tries, num_threads);
}
fn main() {
let args: Vec<String> = env::args().collect();
let (func, tries, num_threads) = parse_flags(&args);
let mut threads = vec![];
for _ in 0..num_threads {
threads.push(thread::spawn(move || loop {
func(tries);
}));
}
for _ in 0..100 {
let (successes, elapsed) = func(tries);
println!("{}/{}\t{:?}", successes, tries, elapsed);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment