Skip to content

Commit

Permalink
Add way to use simd as default, combine default and bytewise implemen…
Browse files Browse the repository at this point in the history
…tation
  • Loading branch information
valaphee committed Mar 22, 2024
1 parent 4b9e109 commit 68b2c5d
Show file tree
Hide file tree
Showing 22 changed files with 182 additions and 358 deletions.
2 changes: 1 addition & 1 deletion src/crc128/bytewise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl Crc<Bytewise<u128>> {
finalize(self.algorithm, crc)
}

const fn update(&self, crc: u128, bytes: &[u8]) -> u128 {
pub(crate) const fn update(&self, crc: u128, bytes: &[u8]) -> u128 {
update_bytewise(crc, self.algorithm.refin, &self.table, bytes)
}

Expand Down
34 changes: 1 addition & 33 deletions src/crc128/default.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,5 @@
use crate::crc128::{finalize, init};
use crate::{Algorithm, Crc, Digest, Implementation};

#[cfg(feature = "no-table-mem-limit")]
impl Implementation for u128 {
type Width = u128;
type Table = ();
}

#[cfg(all(not(feature = "no-table-mem-limit"), feature = "bytewise-mem-limit"))]
impl Implementation for u128 {
type Width = u128;
type Table = [u128; 256];
}

#[cfg(all(
not(feature = "no-table-mem-limit"),
not(feature = "bytewise-mem-limit"),
feature = "slice16-mem-limit"
))]
impl Implementation for u128 {
type Width = u128;
type Table = [[u128; 256]; 16];
}

#[cfg(all(
not(feature = "no-table-mem-limit"),
not(feature = "bytewise-mem-limit"),
not(feature = "slice16-mem-limit")
))]
impl Implementation for u128 {
type Width = u128;
type Table = [u128; 256];
}
use crate::{Algorithm, Crc, Digest};

impl Crc<u128> {
pub const fn new(algorithm: &'static Algorithm<u128>) -> Self {
Expand Down
5 changes: 5 additions & 0 deletions src/crc16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ use crc_catalog::Algorithm;
mod bytewise;
mod default;
mod nolookup;
#[cfg(all(
target_feature = "sse2",
target_feature = "sse4.1",
target_feature = "pclmulqdq"
))]
mod simd;
mod slice16;

Expand Down
2 changes: 1 addition & 1 deletion src/crc16/bytewise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ impl Crc<Bytewise<u16>> {
finalize(self.algorithm, crc)
}

const fn update(&self, crc: u16, bytes: &[u8]) -> u16 {
pub(super) const fn update(&self, crc: u16, bytes: &[u8]) -> u16 {
update_bytewise(crc, self.algorithm.refin, &self.table, bytes)
}

Expand Down
88 changes: 15 additions & 73 deletions src/crc16/default.rs
Original file line number Diff line number Diff line change
@@ -1,61 +1,29 @@
use crate::crc16::{finalize, init};
use crate::{Algorithm, Crc, Digest, Implementation};

#[cfg(feature = "no-table-mem-limit")]
impl Implementation for u16 {
type Width = u16;
type Table = ();
}

#[cfg(all(not(feature = "no-table-mem-limit"), feature = "bytewise-mem-limit"))]
impl Implementation for u16 {
type Width = u16;
type Table = [u16; 256];
}

#[cfg(all(
not(feature = "no-table-mem-limit"),
not(feature = "bytewise-mem-limit"),
feature = "slice16-mem-limit"
))]
impl Implementation for u16 {
type Width = u16;
type Table = [[u16; 256]; 16];
}

#[cfg(all(
not(feature = "no-table-mem-limit"),
not(feature = "bytewise-mem-limit"),
not(feature = "slice16-mem-limit")
))]
impl Implementation for u16 {
type Width = u16;
type Table = [u16; 256];
}
use crate::{Algorithm, Crc, Digest};

impl Crc<u16> {
pub const fn new(algorithm: &'static Algorithm<u16>) -> Self {
#[cfg(feature = "no-table-mem-limit")]
let table = Crc::<crate::NoTable<u16>>::new(algorithm);

#[cfg(all(
not(feature = "no-table-mem-limit"),
not(feature = "bytewise-mem-limit"),
feature = "slice16-mem-limit"
any(
all(
not(feature = "bytewise-mem-limit"),
not(feature = "slice16-mem-limit")
),
feature = "bytewise-mem-limit"
)
))]
let table =
crate::table::crc16_table_slice_16(algorithm.width, algorithm.poly, algorithm.refin);

#[cfg(all(not(feature = "no-table-mem-limit"), feature = "bytewise-mem-limit"))]
let table = crate::table::crc16_table(algorithm.width, algorithm.poly, algorithm.refin);

#[cfg(feature = "no-table-mem-limit")]
#[allow(clippy::let_unit_value)]
let table = ();
let table = Crc::<crate::Bytewise<u16>>::new(algorithm);

#[cfg(all(
not(feature = "no-table-mem-limit"),
not(feature = "bytewise-mem-limit"),
not(feature = "slice16-mem-limit")
feature = "slice16-mem-limit"
))]
let table = crate::table::crc16_table(algorithm.width, algorithm.poly, algorithm.refin);
let table = Crc::<crate::Simd<u16>>::new(algorithm);

Self { algorithm, table }
}
Expand All @@ -67,33 +35,7 @@ impl Crc<u16> {
}

const fn update(&self, crc: u16, bytes: &[u8]) -> u16 {
#[cfg(all(
not(feature = "no-table-mem-limit"),
not(feature = "bytewise-mem-limit"),
feature = "slice16-mem-limit"
))]
{
super::update_slice16(crc, self.algorithm.refin, &self.table, bytes)
}

#[cfg(all(not(feature = "no-table-mem-limit"), feature = "bytewise-mem-limit"))]
{
super::update_bytewise(crc, self.algorithm.refin, &self.table, bytes)
}

#[cfg(feature = "no-table-mem-limit")]
{
super::update_nolookup(crc, self.algorithm, bytes)
}

#[cfg(all(
not(feature = "no-table-mem-limit"),
not(feature = "bytewise-mem-limit"),
not(feature = "slice16-mem-limit")
))]
{
super::update_bytewise(crc, self.algorithm.refin, &self.table, bytes)
}
self.table.update(crc, bytes)
}

pub const fn digest(&self) -> Digest<u16> {
Expand Down
2 changes: 1 addition & 1 deletion src/crc16/nolookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl Crc<NoTable<u16>> {
finalize(self.algorithm, crc)
}

const fn update(&self, crc: u16, bytes: &[u8]) -> u16 {
pub(super) const fn update(&self, crc: u16, bytes: &[u8]) -> u16 {
update_nolookup(crc, self.algorithm, bytes)
}

Expand Down
12 changes: 7 additions & 5 deletions src/crc16/simd.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::crc32::update_simd;
use crate::simd::{SimdValue, SimdValueOps};
use crate::simd::{crc32_update_refin, SimdValue};
use crate::table::{crc16_table_slice_16, crc32_simd_coefficients};
use crate::{Algorithm, Crc, Digest, Simd};

Expand Down Expand Up @@ -28,16 +27,19 @@ impl Crc<Simd<u16>> {
finalize(self.algorithm, crc)
}

fn update(&self, mut crc: u16, bytes: &[u8]) -> u16 {
if !SimdValue::is_supported() || !self.algorithm.refin {
pub(super) fn update(&self, mut crc: u16, bytes: &[u8]) -> u16 {
if !self.algorithm.refin {
return update_slice16(crc, self.algorithm.refin, &self.table.0, bytes);
}

// SAFETY: Both represent numbers
let (bytes_before, chunks, bytes_after) = unsafe { bytes.align_to::<[SimdValue; 4]>() };
crc = update_slice16(crc, self.algorithm.refin, &self.table.0, bytes_before);
if let Some(first_chunk) = chunks.first() {
// SAFETY: All required features are supported, by checking SimdValue::is_supported.
crc = unsafe { update_simd(crc as u32, &self.table.1, first_chunk, chunks) } as u16;
crc =
unsafe { crc32_update_refin(crc as u32, &self.table.1, first_chunk, &chunks[1..]) }
as u16;
}
update_slice16(crc, self.algorithm.refin, &self.table.0, bytes_after)
}
Expand Down
42 changes: 5 additions & 37 deletions src/crc32.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use crate::simd::{SimdValue, SimdValueOps};
use crate::util::crc32;
use crc_catalog::Algorithm;

mod bytewise;
mod default;
mod nolookup;
#[cfg(all(
target_feature = "sse2",
target_feature = "sse4.1",
target_feature = "pclmulqdq"
))]
mod simd;
mod slice16;

Expand Down Expand Up @@ -152,42 +156,6 @@ const fn update_slice16(
crc
}

#[target_feature(enable = "sse2", enable = "sse4.1", enable = "pclmulqdq")]
pub(crate) unsafe fn update_simd(
crc: u32,
coefficients: &[SimdValue; 4],
first_chunk: &[SimdValue; 4],
chunks: &[[SimdValue; 4]],
) -> u32 {
let mut x4 = *first_chunk;

// Apply initial crc value
x4[0] = x4[0].xor(crc as u64);

// Iteratively Fold by 4:
let k1_k2 = coefficients[0];
for chunk in chunks {
for (x, value) in x4.iter_mut().zip(chunk.iter()) {
*x = x.fold_16(k1_k2, *value)
}
}

// Iteratively Fold by 1:
let k3_k4 = coefficients[1];
let mut x = x4[0].fold_16(k3_k4, x4[1]);
x = x.fold_16(k3_k4, x4[2]);
x = x.fold_16(k3_k4, x4[3]);

// Final Reduction of 128-bits
let k5_k6 = coefficients[2];
x = x.fold_8(k3_k4);
x = x.fold_4(k5_k6);

// Barret Reduction
let px_u = coefficients[3];
x.barret_reduction_32(px_u)
}

#[cfg(test)]
mod test {
use crate::{Bytewise, Crc, Implementation, NoTable, Simd, Slice16};
Expand Down
2 changes: 1 addition & 1 deletion src/crc32/bytewise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl Crc<Bytewise<u32>> {
finalize(self.algorithm, crc)
}

const fn update(&self, crc: u32, bytes: &[u8]) -> u32 {
pub(super) const fn update(&self, crc: u32, bytes: &[u8]) -> u32 {
update_bytewise(crc, self.algorithm.refin, &self.table, bytes)
}

Expand Down
88 changes: 15 additions & 73 deletions src/crc32/default.rs
Original file line number Diff line number Diff line change
@@ -1,61 +1,29 @@
use crate::crc32::{finalize, init};
use crate::{Algorithm, Crc, Digest, Implementation};

#[cfg(feature = "no-table-mem-limit")]
impl Implementation for u32 {
type Width = u32;
type Table = ();
}

#[cfg(all(not(feature = "no-table-mem-limit"), feature = "bytewise-mem-limit"))]
impl Implementation for u32 {
type Width = u32;
type Table = [u32; 256];
}

#[cfg(all(
not(feature = "no-table-mem-limit"),
not(feature = "bytewise-mem-limit"),
feature = "slice16-mem-limit"
))]
impl Implementation for u32 {
type Width = u32;
type Table = [[u32; 256]; 16];
}

#[cfg(all(
not(feature = "no-table-mem-limit"),
not(feature = "bytewise-mem-limit"),
not(feature = "slice16-mem-limit")
))]
impl Implementation for u32 {
type Width = u32;
type Table = [u32; 256];
}
use crate::{Algorithm, Crc, Digest};

impl Crc<u32> {
pub const fn new(algorithm: &'static Algorithm<u32>) -> Self {
#[cfg(feature = "no-table-mem-limit")]
let table = Crc::<crate::NoTable<u32>>::new(algorithm);

#[cfg(all(
not(feature = "no-table-mem-limit"),
not(feature = "bytewise-mem-limit"),
feature = "slice16-mem-limit"
any(
all(
not(feature = "bytewise-mem-limit"),
not(feature = "slice16-mem-limit")
),
feature = "bytewise-mem-limit"
)
))]
let table =
crate::table::crc32_table_slice_16(algorithm.width, algorithm.poly, algorithm.refin);

#[cfg(all(not(feature = "no-table-mem-limit"), feature = "bytewise-mem-limit"))]
let table = crate::table::crc32_table(algorithm.width, algorithm.poly, algorithm.refin);

#[cfg(feature = "no-table-mem-limit")]
#[allow(clippy::let_unit_value)]
let table = ();
let table = Crc::<crate::Bytewise<u32>>::new(algorithm);

#[cfg(all(
not(feature = "no-table-mem-limit"),
not(feature = "bytewise-mem-limit"),
not(feature = "slice16-mem-limit")
feature = "slice16-mem-limit"
))]
let table = crate::table::crc32_table(algorithm.width, algorithm.poly, algorithm.refin);
let table = Crc::<crate::Simd<u32>>::new(algorithm);

Self { algorithm, table }
}
Expand All @@ -67,33 +35,7 @@ impl Crc<u32> {
}

const fn update(&self, crc: u32, bytes: &[u8]) -> u32 {
#[cfg(all(
not(feature = "no-table-mem-limit"),
not(feature = "bytewise-mem-limit"),
feature = "slice16-mem-limit"
))]
{
super::update_slice16(crc, self.algorithm.refin, &self.table, bytes)
}

#[cfg(all(not(feature = "no-table-mem-limit"), feature = "bytewise-mem-limit"))]
{
super::update_bytewise(crc, self.algorithm.refin, &self.table, bytes)
}

#[cfg(feature = "no-table-mem-limit")]
{
super::update_nolookup(crc, self.algorithm, bytes)
}

#[cfg(all(
not(feature = "no-table-mem-limit"),
not(feature = "bytewise-mem-limit"),
not(feature = "slice16-mem-limit")
))]
{
super::update_bytewise(crc, self.algorithm.refin, &self.table, bytes)
}
self.table.update(crc, bytes)
}

pub const fn digest(&self) -> Digest<u32> {
Expand Down
Loading

0 comments on commit 68b2c5d

Please sign in to comment.