[go: up one dir, main page]

gxhash 3.4.1

GxHash non-cryptographic algorithm
Documentation
use criterion::{black_box, criterion_group, criterion_main, Criterion};

const PRIME: u64 = 0x00000100000001b3;
const OFFSET: u64 = 0xcbf29ce484222325;

#[inline]
fn hash(hash: u64, value: u64) -> u64 {
    (hash ^ value) * PRIME
}

fn baseline(input: &[u64]) -> u64 {
    let mut h = OFFSET;
    let mut i: usize = 0;
    while i < input.len() {
        h = hash(h, input[i]);

        i = i + 1;
    }
    h
}

fn unrolled(input: &[u64]) -> u64 {
    let mut h: u64 = OFFSET;
    let mut i: usize = 0;
    while i < input.len() {
        h = hash(h, input[i]);
        h = hash(h, input[i + 1]);
        h = hash(h, input[i + 2]);
        h = hash(h, input[i + 3]);
        h = hash(h, input[i + 4]);

        i = i + 5;
    }
    h
}

fn temp(input: &[u64]) -> u64 {
    let mut h: u64 = OFFSET;
    let mut i: usize = 0;
    while i < input.len() {
        let mut tmp: u64 = input[i];
        tmp = hash(tmp, input[i + 1]);
        tmp = hash(tmp, input[i + 2]);
        tmp = hash(tmp, input[i + 3]);
        tmp = hash(tmp, input[i + 4]);

        h = hash(h, tmp);

        i = i + 5;
    }
    h
}

fn laned(input: &[u64]) -> u64 {
    let mut h1: u64 = OFFSET;
    let mut h2: u64 = OFFSET;
    let mut h3: u64 = OFFSET;
    let mut h4: u64 = OFFSET;
    let mut h5: u64 = OFFSET; 
    let mut i: usize = 0;
    while i < input.len() {
        h1 = hash(h1, input[i]);
        h2 = hash(h2, input[i + 1]);
        h3 = hash(h3, input[i + 2]);
        h4 = hash(h4, input[i + 3]);
        h5 = hash(h5, input[i + 4]);

        i = i + 5;
    }
    hash(hash(hash(hash(h1, h2), h3), h4), h5)
}

use rand::Rng;

fn ilp_benchmark(c: &mut Criterion) {
    let mut rng = rand::thread_rng();
    let mut input: [u64; 100000] = [0; 100000];
    for i in 0..input.len() {
        input[i] = rng.gen::<u64>();
    }
    c.bench_function("baseline", |b| b.iter(|| black_box(baseline(&input))));
    c.bench_function("unrolled", |b| b.iter(|| black_box(unrolled(&input))));
    c.bench_function("temp", |b| b.iter(|| black_box(temp(&input))));
    c.bench_function("laned", |b| b.iter(|| black_box(laned(&input))));
}

criterion_group!(benches, ilp_benchmark);
criterion_main!(benches);