-
-
Save mvanotti/7dcb7988804ad0ab5c8a574425e2bf8b to your computer and use it in GitHub Desktop.
Code for testing the behavior of rdrand/rdseed in a given system
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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