Skip to content

Commit

Permalink
runtime: use enum in lieu of fn ptr
Browse files Browse the repository at this point in the history
For small cardinalities branching on an enum should be faster than a func ptr,
thanks to branch prediction
  • Loading branch information
AaronO committed Apr 14, 2023
1 parent 33526a6 commit 073efd1
Showing 1 changed file with 32 additions and 25 deletions.
57 changes: 32 additions & 25 deletions src/simd/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,53 @@ use super::avx2;
use super::sse42;

type VectoredMatchFn = unsafe fn(&mut Bytes);
unsafe fn match_nop_vectored(_: &mut Bytes) {}

pub fn match_uri_vectored(bytes: &mut Bytes) {
static mut MATCH_URI_VECTORED: Option<VectoredMatchFn> = None;
pub enum RuntimeFeature {
Avx2,
Sse42,
Nop,
}

impl RuntimeFeature {
fn detect() -> Self {
if is_x86_feature_detected!("avx2") {
RuntimeFeature::Avx2
} else if is_x86_feature_detected!("sse4.2") {
RuntimeFeature::Sse42
} else {
RuntimeFeature::Nop
}
}
}

static mut RUNTIME_FEATURE: Option<RuntimeFeature> = None;

pub fn match_uri_vectored(bytes: &mut Bytes) {
// SAFETY: calls are guarded by a feature check
unsafe {
if let None = MATCH_URI_VECTORED {
MATCH_URI_VECTORED = if is_x86_feature_detected!("avx2") {
Some(avx2::match_uri_vectored)
} else if is_x86_feature_detected!("sse4.2") {
Some(sse42::match_uri_vectored)
} else {
Some(match_nop_vectored)
};
if let None = RUNTIME_FEATURE {
RUNTIME_FEATURE = Some(RuntimeFeature::detect());
}

if let Some(func_ptr) = MATCH_URI_VECTORED {
(func_ptr)(bytes);
match RUNTIME_FEATURE.as_ref().unwrap() {
RuntimeFeature::Avx2 => avx2::match_uri_vectored(bytes),
RuntimeFeature::Sse42 => sse42::match_uri_vectored(bytes),
RuntimeFeature::Nop => {},
}
}
}

pub fn match_header_value_vectored(bytes: &mut Bytes) {
static mut MATCH_HEADER_VALUE_VECTORED: Option<VectoredMatchFn> = None;

// SAFETY: calls are guarded by a feature check
unsafe {
if let None = MATCH_HEADER_VALUE_VECTORED {
MATCH_HEADER_VALUE_VECTORED = if is_x86_feature_detected!("avx2") {
Some(avx2::match_header_value_vectored)
} else if is_x86_feature_detected!("sse4.2") {
Some(sse42::match_header_value_vectored)
} else {
Some(match_nop_vectored)
};
if let None = RUNTIME_FEATURE {
RUNTIME_FEATURE = Some(RuntimeFeature::detect());
}

if let Some(func_ptr) = MATCH_HEADER_VALUE_VECTORED {
(func_ptr)(bytes);
match RUNTIME_FEATURE.as_ref().unwrap() {
RuntimeFeature::Avx2 => avx2::match_header_value_vectored(bytes),
RuntimeFeature::Sse42 => sse42::match_header_value_vectored(bytes),
RuntimeFeature::Nop => {},
}
}
}

0 comments on commit 073efd1

Please sign in to comment.