Skip to content

Use std::arch for crc checking if available #19

@KodrAus

Description

@KodrAus

There's a comment in the source already but I thought I'd open an issue for this too, now that x86 intrinsics will be available to us in stable Rust 1.27. I've got a crc function I've been using that looks something like:

fn crc32c(buf: &[u8]) -> u32 {
    #[cfg(target_arch = "x86_64")]
    {
        if is_x86_feature_detected!("sse4.2") {
            return unsafe {
                crc32c_sse42(buf)
            }
        }
    }

    crc32c_slice8(buf)
}

#[cfg(target_arch = "x86_64")]
#[target_feature(enable = "sse4.2")]
unsafe fn crc32c_sse42(mut buf: &[u8]) -> u32 {
    use std::arch::x86_64::*;

    let mut crc: u32 = !0;

    while buf.len() >= 4 {
        let b = LE::read_u32(&buf[0..4]);
        crc = _mm_crc32_u32(crc, b);

        buf = &buf[4..];
    }

    for &b in buf {
        crc = _mm_crc32_u8(crc, b);
    }

    !crc
}

With SSE4.2 support that's approximately, roughly somewhere in the ballpark of much faster than our fallback implementation.

I'm not so sure yet how we'd want to approach the target_feature stuff for a library, I'm guessing the static check for SSE4.2 support would be better than a runtime check? I also excluded 32bit because I didn't need it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions