From 0641dac7f0aa6c055fca8ab633ad85859d0ddd97 Mon Sep 17 00:00:00 2001 From: mat Date: Thu, 23 Mar 2023 20:20:13 -0500 Subject: simd number arrays --- azalea-nbt/src/encode.rs | 73 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 4 deletions(-) (limited to 'azalea-nbt/src/encode.rs') 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::(l.len() as i32).unwrap(); - for &v in l { - writer.write_i32::(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::(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::(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::(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::(l) }; + writer.write_all(&l).unwrap(); + position += 2; + } + // x1 ... just a normal write_i32 + if l.len() - position >= 1 { + writer.write_i32::(l[position]).unwrap(); } } NbtList::Long(l) => { writer.write_i32::(l.len() as i32).unwrap(); - for &v in l { - writer.write_i64::(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::(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::(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::(l) }; + writer.write_all(&l).unwrap(); + position += 2; + } + // x1 ... just a normal write_i32 + if l.len() - position >= 1 { + writer.write_i64::(l[position]).unwrap(); } } NbtList::Float(l) => { -- cgit v1.2.3