aboutsummaryrefslogtreecommitdiff
path: root/azalea-nbt/src/encode.rs
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2023-03-23 20:20:13 -0500
committermat <github@matdoes.dev>2023-03-23 20:20:13 -0500
commit0641dac7f0aa6c055fca8ab633ad85859d0ddd97 (patch)
tree56a22a7872cd1309721c05a770bebac05d0adedb /azalea-nbt/src/encode.rs
parent95925b64fa0e75a7567c9b2361d90d477fc9bf55 (diff)
downloadazalea-drasl-0641dac7f0aa6c055fca8ab633ad85859d0ddd97.tar.xz
simd number arrays
Diffstat (limited to 'azalea-nbt/src/encode.rs')
-rwxr-xr-xazalea-nbt/src/encode.rs73
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) => {