Skip to content

Commit

Permalink
test: conditionally use simd variant
Browse files Browse the repository at this point in the history
  • Loading branch information
rymnc committed Dec 29, 2024
1 parent d837288 commit 6960c51
Showing 1 changed file with 68 additions and 30 deletions.
98 changes: 68 additions & 30 deletions fuel-vm/src/interpreter/memory.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![cfg(feature = "alloc")]

#[cfg(feature = "experimental")]
use core::simd::u8x16;
use core::simd::{u8x16, u8x32, u8x64};

use super::{
internal::inc_pc,
Expand Down Expand Up @@ -1040,37 +1040,75 @@ fn slice_eq(a: &[u8], b: &[u8]) -> bool {
return false;
}

// because we're using simd, we can parallelize by a factor of 4
let mut res_a = false;
let mut res_b = false;
let mut res_c = false;
let mut res_d = false;

let chunks_a = a.chunks_exact(16);
let chunks_b = b.chunks_exact(16);
let remainder_a = chunks_a.remainder();
let remainder_b = chunks_b.remainder();

for i in (0..chunks_a.len()).step_by(4) {
let simd_a = u8x16::from_slice(&a[i..i + 16]);
let simd_b = u8x16::from_slice(&b[i..i + 16]);
res_a |= simd_a != simd_b;

let simd_a = u8x16::from_slice(&a[i + 16..i + 32]);
let simd_b = u8x16::from_slice(&b[i + 16..i + 32]);
res_b |= simd_a != simd_b;

let simd_a = u8x16::from_slice(&a[i + 32..i + 48]);
let simd_b = u8x16::from_slice(&b[i + 32..i + 48]);
res_c |= simd_a != simd_b;

let simd_a = u8x16::from_slice(&a[i + 48..i + 64]);
let simd_b = u8x16::from_slice(&b[i + 48..i + 64]);
res_d |= simd_a != simd_b;
enum SimdVariant {
U8x16,
U8x32,
U8x64,
}

// check the remainder
remainder_a == remainder_b && res_a && res_b && res_c && res_d
impl SimdVariant {
fn chunk_size(&self) -> usize{
match &self {
SimdVariant::U8x16 => 16,
SimdVariant::U8x32 => 32,
SimdVariant::U8x64 => 64,
}
}
}

// we check if the number of bytes is divisible by 16, 32, 64.
// we choose the largest number that has the smallest remainder

let remainder_16 = a.len() % 16;
let remainder_32 = a.len() % 32;
let remainder_64 = a.len() % 64;

// based on the smallest remainder, we then use the appropriate simd instruction
// to compare the slices
let variant = if remainder_16 < remainder_32 {
if remainder_16 < remainder_64 {
SimdVariant::U8x16
} else {
SimdVariant::U8x64
}
} else {
if remainder_32 < remainder_64 {
SimdVariant::U8x32
} else {
SimdVariant::U8x64
}
};

let chunks = a.chunks_exact(variant.chunk_size());
let remainder = chunks.remainder();

for (chunk_a, chunk_b) in chunks.zip(b.chunks_exact(variant.chunk_size())) {
match variant {
SimdVariant::U8x16 => {
let simd_a = u8x16::from_slice(chunk_a);
let simd_b = u8x16::from_slice(chunk_b);
if simd_a != simd_b {
return false;
}
}
SimdVariant::U8x32 => {
let simd_a = u8x32::from_slice(chunk_a);
let simd_b = u8x32::from_slice(chunk_b);
if simd_a != simd_b {
return false;
}
}
SimdVariant::U8x64 => {
let simd_a = u8x64::from_slice(chunk_a);
let simd_b = u8x64::from_slice(chunk_b);
if simd_a != simd_b {
return false;
}
}
}
}

remainder == &b[a.len() - remainder.len()..]
}
#[cfg(not(feature = "experimental"))]
{
Expand Down

0 comments on commit 6960c51

Please sign in to comment.