diff options
| author | mat <github@matdoes.dev> | 2023-03-23 20:20:13 -0500 |
|---|---|---|
| committer | mat <github@matdoes.dev> | 2023-03-23 20:20:13 -0500 |
| commit | 0641dac7f0aa6c055fca8ab633ad85859d0ddd97 (patch) | |
| tree | 56a22a7872cd1309721c05a770bebac05d0adedb /azalea-nbt/src/encode.rs | |
| parent | 95925b64fa0e75a7567c9b2361d90d477fc9bf55 (diff) | |
| download | azalea-drasl-0641dac7f0aa6c055fca8ab633ad85859d0ddd97.tar.xz | |
simd number arrays
Diffstat (limited to 'azalea-nbt/src/encode.rs')
| -rwxr-xr-x | azalea-nbt/src/encode.rs | 73 |
1 files changed, 69 insertions, 4 deletions
diff --git a/azalea-nbt/src/encode.rs b/azalea-nbt/src/encode.rs index bf56c223..f5195327 100755 --- a/azalea-nbt/src/encode.rs +++ b/azalea-nbt/src/encode.rs @@ -2,6 +2,7 @@ use crate::tag::*; use azalea_buf::McBufWritable; use byteorder::{WriteBytesExt, BE}; use flate2::write::{GzEncoder, ZlibEncoder}; +use packed_simd_2::{i32x16, i32x2, i32x4, i32x8, i64x2, i64x4, i64x8}; use std::io::Write; #[inline(always)] @@ -81,14 +82,78 @@ fn write_list(writer: &mut impl Write, value: &NbtList) { } NbtList::Int(l) => { writer.write_i32::<BE>(l.len() as i32).unwrap(); - for &v in l { - writer.write_i32::<BE>(v).unwrap(); + // flip the bits to big endian with simd + let l = l.as_slice(); + let mut position = 0; + // x16 + while l.len() - position >= 16 { + let l = unsafe { i32x16::from_slice_unaligned_unchecked(&l[position..]) }; + l.to_be(); + let l = unsafe { std::mem::transmute::<i32x16, [u8; 64]>(l) }; + writer.write_all(&l).unwrap(); + position += 16; + } + // x8 + if l.len() - position >= 8 { + let l = unsafe { i32x8::from_slice_unaligned_unchecked(&l[position..]) }; + l.to_be(); + let l = unsafe { std::mem::transmute::<i32x8, [u8; 32]>(l) }; + writer.write_all(&l).unwrap(); + position += 8; + } + // x4 + if l.len() - position >= 4 { + let l = unsafe { i32x4::from_slice_unaligned_unchecked(&l[position..]) }; + l.to_be(); + let l = unsafe { std::mem::transmute::<i32x4, [u8; 16]>(l) }; + writer.write_all(&l).unwrap(); + position += 4; + } + // x2 + if l.len() - position >= 2 { + let l = unsafe { i32x2::from_slice_unaligned_unchecked(&l[position..]) }; + l.to_be(); + let l = unsafe { std::mem::transmute::<i32x2, [u8; 8]>(l) }; + writer.write_all(&l).unwrap(); + position += 2; + } + // x1 ... just a normal write_i32 + if l.len() - position >= 1 { + writer.write_i32::<BE>(l[position]).unwrap(); } } NbtList::Long(l) => { writer.write_i32::<BE>(l.len() as i32).unwrap(); - for &v in l { - writer.write_i64::<BE>(v).unwrap(); + // flip the bits to big endian with simd + let l = l.as_slice(); + let mut position = 0; + // x16 + while l.len() - position >= 8 { + let l = unsafe { i64x8::from_slice_unaligned_unchecked(&l[position..]) }; + l.to_be(); + let l = unsafe { std::mem::transmute::<i64x8, [u8; 64]>(l) }; + writer.write_all(&l).unwrap(); + position += 8; + } + // x4 + if l.len() - position >= 4 { + let l = unsafe { i64x4::from_slice_unaligned_unchecked(&l[position..]) }; + l.to_be(); + let l = unsafe { std::mem::transmute::<i64x4, [u8; 32]>(l) }; + writer.write_all(&l).unwrap(); + position += 4; + } + // x2 + if l.len() - position >= 2 { + let l = unsafe { i64x2::from_slice_unaligned_unchecked(&l[position..]) }; + l.to_be(); + let l = unsafe { std::mem::transmute::<i64x2, [u8; 16]>(l) }; + writer.write_all(&l).unwrap(); + position += 2; + } + // x1 ... just a normal write_i32 + if l.len() - position >= 1 { + writer.write_i64::<BE>(l[position]).unwrap(); } } NbtList::Float(l) => { |
