Skip to content

Commit 94e0c64

Browse files
authored
Merge pull request #102 from LebedevRI/develop
Benchmark attempt
2 parents 6744f33 + 5c6fa88 commit 94e0c64

File tree

10 files changed

+115
-21
lines changed

10 files changed

+115
-21
lines changed

.github/workflows/CI-linux.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ jobs:
595595
cd "${{ env.SRC_DIR }}"
596596
cargo miri nextest run --target ${{ env.RUST_TARGET }}
597597
- name: Run tests under Sanitizer
598-
timeout-minutes: 3
598+
timeout-minutes: 5
599599
if: inputs.job-flavor == 'ASAN' || inputs.job-flavor == 'MSAN' || inputs.job-flavor == 'TSAN'
600600
run: |
601601
set -xe
@@ -617,6 +617,14 @@ jobs:
617617
export ${{ inputs.job-flavor }}_OPTIONS="allocator_may_return_null=1"
618618
cd "${{ env.SRC_DIR }}"
619619
cargo test --all-targets $BUILD_ARGS --target ${{ env.RUST_TARGET }} --profile ${{ inputs.build-profile }}-sanitized
620+
- name: Dry-run benchmarks
621+
timeout-minutes: 1
622+
if: inputs.job-flavor == 'plain'
623+
run: |
624+
set -xe
625+
. "$HOME/.cargo/env"
626+
cd "${{ env.SRC_DIR }}"
627+
cargo bench --target ${{ env.RUST_TARGET }} --profile ${{ inputs.build-profile }} --benches -- --quick --warm-up-time 1e-9 --measurement-time 1e-9 --noplot
620628
- name: Perform SonarQube static analysis
621629
timeout-minutes: 1
622630
if: inputs.job-flavor == 'SonarQube'

.github/workflows/CI-macOS.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ on:
44
os:
55
required: true
66
type: string
7+
os-ver:
8+
required: true
9+
type: string
710
runs-on:
811
required: true
912
type: string
@@ -32,6 +35,7 @@ env:
3235
RUSTFLAGS: "-Dwarnings"
3336
SRC_DIR: ${{ github.workspace }}/rawspeed.rs
3437
CODECOV_TOKEN_EXISTS: ${{ secrets.CODECOV_TOKEN != '' }}
38+
MACOSX_DEPLOYMENT_TARGET: ${{ inputs.os-ver }}
3539

3640
jobs:
3741
macOS:
@@ -251,3 +255,10 @@ jobs:
251255
files: ${{ env.SRC_DIR }}/codecov.json
252256
root_dir: ${{ env.SRC_DIR }}
253257
fail_ci_if_error: true
258+
- name: Dry-run benchmarks
259+
timeout-minutes: 1
260+
run: |
261+
set -xe
262+
. "$HOME/.cargo/env"
263+
cd "$SRC_DIR"
264+
cargo bench --profile ${{ inputs.build-profile }} --benches -- --quick --warm-up-time 1e-9 --measurement-time 1e-9 --noplot

.github/workflows/CI.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ jobs:
126126
uses: ./.github/workflows/CI-macOS.yml
127127
with:
128128
os: ${{ matrix.compiler.os }}
129+
os-ver: ${{ matrix.compiler.os-ver }}
129130
runs-on: ${{ matrix.compiler.os }}-${{ matrix.compiler.os-ver }}
130131
builder-host: ${{ matrix.compiler.host }}
131132
builder-target: ${{ matrix.compiler.target }}

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ members = [
3434
"src/metadata/xmltokendesparsifier",
3535
"src/metadata/xmltokenizer",
3636
"src/misc/md5",
37+
"benches/misc/md5",
3738
"src/parsers",
3839
"src/parsers/rawparser",
3940
"src/std",

benches/misc/md5/Cargo.toml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[package]
2+
name = "rawspeed-bench-md5"
3+
version.workspace = true
4+
authors.workspace = true
5+
edition.workspace = true
6+
rust-version.workspace = true
7+
documentation.workspace = true
8+
homepage.workspace = true
9+
repository.workspace = true
10+
license.workspace = true
11+
12+
[lints]
13+
workspace = true
14+
15+
[dev-dependencies]
16+
rawspeed-misc-md5 = { path = "../../../src/misc/md5" }
17+
criterion = { version = "0.8.2", default-features = false, features = [] }
18+
19+
[[bench]]
20+
name = "rawspeed-bench-md5"
21+
path = "mod.rs"
22+
harness = false

benches/misc/md5/mod.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
use criterion::{
2+
AxisScale, BenchmarkId, Criterion, PlotConfiguration, Throughput,
3+
criterion_group, criterion_main,
4+
};
5+
use rawspeed_misc_md5::md5::{self, MD5};
6+
7+
#[inline(never)]
8+
fn md5_slice(input: &[u8]) -> md5::MD5State {
9+
let mut hasher = MD5::default();
10+
hasher.extend(input);
11+
hasher.flush()
12+
}
13+
14+
fn md5_benchmark(c: &mut Criterion) {
15+
static KIB: usize = 1024;
16+
17+
let sizes: Box<dyn Iterator<Item = _>> = if true {
18+
let sizes = [4 * KIB].into_iter();
19+
Box::new(sizes)
20+
} else {
21+
let sizes =
22+
core::iter::successors(Some(1_usize), |&prev| prev.checked_mul(2))
23+
.take_while(|s| *s <= 2 * KIB * KIB);
24+
let sizes = [0].into_iter().chain(sizes);
25+
Box::new(sizes)
26+
};
27+
28+
let mut group = c.benchmark_group("md5");
29+
group.plot_config(
30+
PlotConfiguration::default().summary_scale(AxisScale::Logarithmic),
31+
);
32+
for size in sizes {
33+
group.throughput(Throughput::Bytes(size.try_into().unwrap()));
34+
group.bench_with_input(
35+
BenchmarkId::from_parameter(size),
36+
&size,
37+
|b, size| {
38+
let input = core::hint::black_box(vec![0; *size]);
39+
b.iter(|| md5_slice(input.as_slice()));
40+
},
41+
);
42+
}
43+
group.finish();
44+
}
45+
46+
criterion_group!(benches, md5_benchmark);
47+
criterion_main!(benches);

src/misc/md5/md5/mod.rs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -168,29 +168,33 @@ impl MD5State {
168168
}
169169

170170
#[inline]
171-
fn md5_compress(&mut self, block: &MD5Block) {
172-
let mut schedule: [u32; 16] = Default::default();
173-
174-
for (s, bytes) in schedule.iter_mut().zip(block.0.chunks_exact(32 / 8))
175-
{
176-
*s = u32::from_le_bytes(bytes.try_into().unwrap());
177-
}
171+
#[expect(clippy::many_single_char_names)]
172+
fn round<S>(&mut self, r: MD5Round, step: &StepParams, schedule: S)
173+
where
174+
S: Fn(usize) -> u32,
175+
{
176+
let [a, b, c, d] = self.0;
177+
let expr = r.get_expr(*self);
178+
let a = a
179+
.wrapping_add(expr)
180+
.wrapping_add(step.t)
181+
.wrapping_add(schedule(step.k))
182+
.rotate_left(step.s)
183+
.wrapping_add(b);
184+
self.0 = [d, a, b, c];
185+
}
178186

179-
let round_impl = |r: MD5Round, tmp: MD5State, step: &StepParams| {
180-
let [a, b, _rest @ ..] = tmp.0;
181-
let expr = r.get_expr(tmp);
182-
let a = a
183-
.wrapping_add(expr)
184-
.wrapping_add(step.t)
185-
.wrapping_add(*schedule.get(step.k).unwrap());
186-
b.wrapping_add(a.rotate_left(step.s))
187+
#[inline]
188+
fn md5_compress(&mut self, block: &MD5Block) {
189+
let schedule = |k: usize| -> u32 {
190+
let bytes = block.0.chunks_exact(32 / 8).nth(k).unwrap();
191+
u32::from_le_bytes(bytes.try_into().unwrap())
187192
};
188193

189194
let mut tmp = *self;
190195
for (round, steps) in STAGES.iter().enumerate() {
191196
for step in steps {
192-
tmp.0[0] = round_impl(MD5Round(round), tmp, step);
193-
tmp.0.rotate_right(1);
197+
tmp.round(MD5Round(round), step, schedule);
194198
}
195199
}
196200

src/std/wrapping_numerics_arith/tests/add_unsigned_and_signed.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fn run_test(lhs: BoundUnsigned<T>, rhs: U) {
3535
}
3636

3737
#[test]
38-
#[cfg(not(miri))]
38+
#[cfg_attr(miri, ignore)]
3939
fn exhaustive_test() {
4040
for bound in T::MIN..=T::MAX {
4141
let Some(bound) = Bound::new(bound) else {

src/std/wrapping_numerics_arith/tests/add_unsigned_and_unsigned.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn run_test(lhs: BoundUnsigned<T>, rhs: T) {
2323
}
2424

2525
#[test]
26-
#[cfg(not(miri))]
26+
#[cfg_attr(miri, ignore)]
2727
fn add_test_exhaustive() {
2828
for bound in u8::MIN..=u8::MAX {
2929
let Some(bound) = Bound::new(bound) else {

tests/metadata/camerasxml_parser/xmllint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#[cfg(test)]
22
mod tests {
33
#[test]
4-
#[cfg(not(miri))]
4+
#[cfg_attr(miri, ignore)]
55
fn xmllint() -> Result<(), Box<dyn core::error::Error>> {
66
use rawspeed_metadata_camerasxml_parser::camerasxml_parser;
77
let camerasxml_path =

0 commit comments

Comments
 (0)