Skip to content

Commit

Permalink
Add no no_std support (#74)
Browse files Browse the repository at this point in the history
* Add no `no_std` support

# Conflicts:
#	.github/workflows/build_test.yml
#	Cargo.toml

* More readme

---------

Co-authored-by: Moritz Mœller <[email protected]>
  • Loading branch information
ogxd and virtualritz authored May 27, 2024
1 parent b85cfb9 commit 5a23285
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 5 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = []
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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**
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/gxhash/platform/arm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
2 changes: 1 addition & 1 deletion src/gxhash/platform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<State>();
// 4KiB is the default page size for most systems, and conservative for other systems such as MacOS ARM (16KiB)
Expand Down
2 changes: 1 addition & 1 deletion src/gxhash/platform/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
7 changes: 5 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -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))]

Expand All @@ -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::*;

0 comments on commit 5a23285

Please sign in to comment.