mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Change hand-picked RNGs back to SmallRng
While `Xoshiro256+` is faster on 64-bit, it has low linear complexity in the lower three bits, which *are* used when generating dither. Also, while `Xoshiro128StarStar` access one less variable from the heap, multiplication is generally slower than addition in hardware.
This commit is contained in:
parent
4c89a721ee
commit
ff3648434b
3 changed files with 7 additions and 34 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -1288,7 +1288,6 @@ dependencies = [
|
||||||
"portaudio-rs",
|
"portaudio-rs",
|
||||||
"rand",
|
"rand",
|
||||||
"rand_distr",
|
"rand_distr",
|
||||||
"rand_xoshiro",
|
|
||||||
"rodio",
|
"rodio",
|
||||||
"sdl2",
|
"sdl2",
|
||||||
"shell-words",
|
"shell-words",
|
||||||
|
@ -1899,15 +1898,6 @@ dependencies = [
|
||||||
"rand_core",
|
"rand_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_xoshiro"
|
|
||||||
version = "0.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.2.10"
|
version = "0.2.10"
|
||||||
|
|
|
@ -47,9 +47,8 @@ lewton = "0.10"
|
||||||
ogg = "0.8"
|
ogg = "0.8"
|
||||||
|
|
||||||
# Dithering
|
# Dithering
|
||||||
rand = "0.8"
|
rand = { version = "0.8", features = ["small_rng"] }
|
||||||
rand_distr = "0.4"
|
rand_distr = "0.4"
|
||||||
rand_xoshiro = "0.6"
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
alsa-backend = ["alsa"]
|
alsa-backend = ["alsa"]
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use rand::rngs::SmallRng;
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
use rand_distr::{Distribution, Normal, Triangular, Uniform};
|
use rand_distr::{Distribution, Normal, Triangular, Uniform};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -41,29 +42,12 @@ impl fmt::Display for dyn Ditherer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// `SmallRng` is 33% faster than `ThreadRng`, but we can do even better.
|
fn create_rng() -> SmallRng {
|
||||||
// `SmallRng` defaults to `Xoshiro256PlusPlus` on 64-bit platforms and
|
SmallRng::from_entropy()
|
||||||
// `Xoshiro128PlusPlus` on 32-bit platforms. These are excellent for the
|
|
||||||
// general case. In our case of just 64-bit floating points, we can make
|
|
||||||
// some optimizations. Compared to `SmallRng`, these hand-picked generators
|
|
||||||
// improve performance by another 9% on 64-bit platforms and 2% on 32-bit
|
|
||||||
// platforms.
|
|
||||||
//
|
|
||||||
// For reference, see https://prng.di.unimi.it. Note that we do not use
|
|
||||||
// `Xoroshiro128Plus` or `Xoshiro128Plus` because they display low linear
|
|
||||||
// complexity in the lower four bits, which is not what we want:
|
|
||||||
// linearization is the very point of dithering.
|
|
||||||
#[cfg(target_pointer_width = "64")]
|
|
||||||
type Rng = rand_xoshiro::Xoshiro256Plus;
|
|
||||||
#[cfg(not(target_pointer_width = "64"))]
|
|
||||||
type Rng = rand_xoshiro::Xoshiro128StarStar;
|
|
||||||
|
|
||||||
fn create_rng() -> Rng {
|
|
||||||
Rng::from_entropy()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TriangularDitherer {
|
pub struct TriangularDitherer {
|
||||||
cached_rng: Rng,
|
cached_rng: SmallRng,
|
||||||
distribution: Triangular<f64>,
|
distribution: Triangular<f64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +74,7 @@ impl TriangularDitherer {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GaussianDitherer {
|
pub struct GaussianDitherer {
|
||||||
cached_rng: Rng,
|
cached_rng: SmallRng,
|
||||||
distribution: Normal<f64>,
|
distribution: Normal<f64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +103,7 @@ impl GaussianDitherer {
|
||||||
pub struct HighPassDitherer {
|
pub struct HighPassDitherer {
|
||||||
active_channel: usize,
|
active_channel: usize,
|
||||||
previous_noises: [f64; NUM_CHANNELS],
|
previous_noises: [f64; NUM_CHANNELS],
|
||||||
cached_rng: Rng,
|
cached_rng: SmallRng,
|
||||||
distribution: Uniform<f64>,
|
distribution: Uniform<f64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue