summaryrefslogtreecommitdiffstats
path: root/third_party/rust/getrandom/benches
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /third_party/rust/getrandom/benches
parentInitial commit. (diff)
downloadfirefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz
firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/getrandom/benches')
-rw-r--r--third_party/rust/getrandom/benches/mod.rs94
1 files changed, 94 insertions, 0 deletions
diff --git a/third_party/rust/getrandom/benches/mod.rs b/third_party/rust/getrandom/benches/mod.rs
new file mode 100644
index 0000000000..11be47eb75
--- /dev/null
+++ b/third_party/rust/getrandom/benches/mod.rs
@@ -0,0 +1,94 @@
+#![feature(test)]
+extern crate test;
+
+use std::{
+ alloc::{alloc_zeroed, dealloc, Layout},
+ ptr::NonNull,
+};
+
+// AlignedBuffer is like a Box<[u8; N]> except that it is always N-byte aligned
+struct AlignedBuffer<const N: usize>(NonNull<[u8; N]>);
+
+impl<const N: usize> AlignedBuffer<N> {
+ fn layout() -> Layout {
+ Layout::from_size_align(N, N).unwrap()
+ }
+
+ fn new() -> Self {
+ let p = unsafe { alloc_zeroed(Self::layout()) } as *mut [u8; N];
+ Self(NonNull::new(p).unwrap())
+ }
+
+ fn buf(&mut self) -> &mut [u8; N] {
+ unsafe { self.0.as_mut() }
+ }
+}
+
+impl<const N: usize> Drop for AlignedBuffer<N> {
+ fn drop(&mut self) {
+ unsafe { dealloc(self.0.as_ptr() as *mut u8, Self::layout()) }
+ }
+}
+
+// Used to benchmark the throughput of getrandom in an optimal scenario.
+// The buffer is hot, and does not require initialization.
+#[inline(always)]
+fn bench<const N: usize>(b: &mut test::Bencher) {
+ let mut ab = AlignedBuffer::<N>::new();
+ let buf = ab.buf();
+ b.iter(|| {
+ getrandom::getrandom(&mut buf[..]).unwrap();
+ test::black_box(&buf);
+ });
+ b.bytes = N as u64;
+}
+
+// Used to benchmark the throughput of getrandom is a slightly less optimal
+// scenario. The buffer is still hot, but requires initialization.
+#[inline(always)]
+fn bench_with_init<const N: usize>(b: &mut test::Bencher) {
+ let mut ab = AlignedBuffer::<N>::new();
+ let buf = ab.buf();
+ b.iter(|| {
+ for byte in buf.iter_mut() {
+ *byte = 0;
+ }
+ getrandom::getrandom(&mut buf[..]).unwrap();
+ test::black_box(&buf);
+ });
+ b.bytes = N as u64;
+}
+
+// 32 bytes (256-bit) is the seed sized used for rand::thread_rng
+const SEED: usize = 32;
+// Common size of a page, 4 KiB
+const PAGE: usize = 4096;
+// Large buffer to get asymptotic performance, 2 MiB
+const LARGE: usize = 1 << 21;
+
+#[bench]
+fn bench_seed(b: &mut test::Bencher) {
+ bench::<SEED>(b);
+}
+#[bench]
+fn bench_seed_init(b: &mut test::Bencher) {
+ bench_with_init::<SEED>(b);
+}
+
+#[bench]
+fn bench_page(b: &mut test::Bencher) {
+ bench::<PAGE>(b);
+}
+#[bench]
+fn bench_page_init(b: &mut test::Bencher) {
+ bench_with_init::<PAGE>(b);
+}
+
+#[bench]
+fn bench_large(b: &mut test::Bencher) {
+ bench::<LARGE>(b);
+}
+#[bench]
+fn bench_large_init(b: &mut test::Bencher) {
+ bench_with_init::<LARGE>(b);
+}