From 5a23285e3ede7166db90c0ede26a4d06cc8d8ac7 Mon Sep 17 00:00:00 2001 From: Olivier Giniaux Date: Mon, 27 May 2024 14:54:33 +0200 Subject: [PATCH] Add no `no_std` support (#74) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add no `no_std` support # Conflicts: # .github/workflows/build_test.yml # Cargo.toml * More readme --------- Co-authored-by: Moritz Mœller --- Cargo.toml | 2 ++ README.md | 19 +++++++++++++++++++ src/gxhash/platform/arm.rs | 2 +- src/gxhash/platform/mod.rs | 2 +- src/gxhash/platform/x86.rs | 2 +- src/lib.rs | 7 +++++-- 6 files changed, 29 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c93eb90..61bd770 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,8 @@ categories = ["algorithms", "data-structures", "no-std"] exclude = ["article/*"] [features] +default = ["std"] +std = [] # Only relevant for throughput benchmarks bench-csv = [] bench-md = [] diff --git a/README.md b/README.md index 94eb1e7..0959b39 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,9 @@ Thanks to this, GxHash passes all [SMHasher](https://github.com/rurban/smhasher) Check out the [paper](https://github.com/ogxd/gxhash-rust/blob/main/article/article.pdf) for more technical details. +### 0 Dependencies 📦 +GxHash has 0 cargo dependency. The `Hasher` and `Hashset`/`Hashmap` convenience types require the standard library, enabled by default with the `std` feature. + ## Portability > **Important** @@ -50,6 +53,22 @@ GxHash is compatible with: ### Hashes Stability All generated hashes for a given version of GxHash are stable, meaning that for a given input the output hash will be the same across all supported platforms. +### `no_std` + +The `std` feature flag enables the `HashMap`/`HashSet` container convenience type aliases. This is on by default. Disable to make the crate `no_std`: + +```toml +[dependencies.gxhash] +... +default-features = false +``` + +### `hybrid` + +The `hybrid` feature flag enables a hybrid implementation of GxHash. This is disabled by default. When `hybrid` feature is enabled and for CPUs that supports it, GxHash will use wider registers and instructions (`VAES` + `AVX2`), which can lead to a significant performance improvement for large inputs. This preserves hashes stability, meaning that hashes generated with or without the `hybrid` feature are the same for a given input and seed. + +*Note: Even without this feature enabled GxHash is already the fastest option out there. We recommend enabling this feature only when inputs can be larger than a few hundred bytes, see the benchmarks below.* + ## Benchmarks [![Benchmark](https://github.com/ogxd/gxhash/actions/workflows/bench.yml/badge.svg)](https://github.com/ogxd/gxhash/actions/workflows/bench.yml) diff --git a/src/gxhash/platform/arm.rs b/src/gxhash/platform/arm.rs index 90269a8..a262583 100644 --- a/src/gxhash/platform/arm.rs +++ b/src/gxhash/platform/arm.rs @@ -27,7 +27,7 @@ pub unsafe fn get_partial_safe(data: *const State, len: usize) -> State { // Temporary buffer filled with zeros let mut buffer = [0i8; VECTOR_SIZE]; // Copy data into the buffer - std::ptr::copy(data as *const i8, buffer.as_mut_ptr(), len); + core::ptr::copy(data as *const i8, buffer.as_mut_ptr(), len); // Load the buffer into a __m256i vector let partial_vector = vld1q_s8(buffer.as_ptr()); vaddq_s8(partial_vector, vdupq_n_s8(len as i8)) diff --git a/src/gxhash/platform/mod.rs b/src/gxhash/platform/mod.rs index 0feb928..7961016 100644 --- a/src/gxhash/platform/mod.rs +++ b/src/gxhash/platform/mod.rs @@ -8,7 +8,7 @@ mod platform; pub use platform::*; -use std::mem::size_of; +use core::mem::size_of; pub(crate) const VECTOR_SIZE: usize = size_of::(); // 4KiB is the default page size for most systems, and conservative for other systems such as MacOS ARM (16KiB) diff --git a/src/gxhash/platform/x86.rs b/src/gxhash/platform/x86.rs index 62c058a..67f52cf 100644 --- a/src/gxhash/platform/x86.rs +++ b/src/gxhash/platform/x86.rs @@ -27,7 +27,7 @@ pub unsafe fn get_partial_safe(data: *const State, len: usize) -> State { // Temporary buffer filled with zeros let mut buffer = [0i8; VECTOR_SIZE]; // Copy data into the buffer - std::ptr::copy(data as *const i8, buffer.as_mut_ptr(), len); + core::ptr::copy(data as *const i8, buffer.as_mut_ptr(), len); // Load the buffer into a __m256i vector let partial_vector = _mm_loadu_si128(buffer.as_ptr() as *const State); _mm_add_epi8(partial_vector, _mm_set1_epi8(len as i8)) diff --git a/src/lib.rs b/src/lib.rs index 692058f..9b59d44 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +#![cfg_attr(not(feature = "std"), no_std)] // Hybrid SIMD width usage currently requires unstable 'stdsimd' #![cfg_attr(feature = "hybrid", feature(stdarch_x86_avx512))] @@ -9,7 +10,9 @@ compile_error!{"Gxhash requires aes intrinsics. Make sure the processor supports #[rustfmt::skip] mod gxhash; -mod hasher; - pub use crate::gxhash::*; + +#[cfg(feature = "std")] +mod hasher; +#[cfg(feature = "std")] pub use crate::hasher::*; \ No newline at end of file