Skip to content

Commit 0cdea0d

Browse files
fix(simd-util): allow different align offsets (#612)
This handles the case where `prev` and `current` from `copy_and_get_diff` have different align offsets. On my machine (aarch64-unknown-linux-gnu) the code still usually takes the "optimized" path where the align offsets are the same (`before_prev.len() == before_current.len()`), so this shouldn't cause significant performance issues. Fixes #608 --------- Co-authored-by: Andrew Gazelka <andrew.gazelka@gmail.com>
1 parent 4dc26b0 commit 0cdea0d

File tree

7 files changed

+265
-79
lines changed

7 files changed

+265
-79
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ version = '0.10.6'
205205
[workspace.dependencies.sha2]
206206
version = '0.10.8'
207207

208+
[workspace.dependencies.simd-utils]
209+
path = 'crates/simd-utils'
210+
208211
[workspace.dependencies.tokio-util]
209212
features = ['full']
210213
version = '0.7.12'

crates/hyperion/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ anyhow = {workspace = true}
2323
base64 = {workspace = true}
2424
geometry = {workspace = true}
2525
bitfield-struct = {workspace = true}
26+
simd-utils = {workspace = true}
2627
bitvec = {workspace = true}
2728
heck = {workspace = true}
2829
papaya = {workspace = true}

crates/hyperion/src/alloc.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ unsafe extern "C-unwind" fn aligned_malloc(size: ecs_size_t) -> *mut core::ffi::
3131
};
3232

3333
let ptr = unsafe { alloc(layout) };
34+
3435
if ptr.is_null() {
3536
return null_mut();
3637
}
@@ -50,6 +51,7 @@ unsafe extern "C-unwind" fn aligned_calloc(size: ecs_size_t) -> *mut core::ffi::
5051
std::ptr::write_bytes(ptr, 0, size as usize);
5152
};
5253
}
54+
5355
ptr
5456
}
5557

crates/hyperion/src/egress/sync_entity_state.rs

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -40,27 +40,61 @@ impl Module for EntityStateSyncModule {
4040
.singleton()
4141
.multi_threaded()
4242
.kind::<flecs::pipeline::OnStore>()
43-
.each_entity(|entity, (compose, net, prev, current)| {
44-
let world = entity.world();
45-
if prev == current {
46-
return;
43+
.run(|mut table| {
44+
while table.next() {
45+
let count = table.count();
46+
let world = table.world();
47+
48+
unsafe {
49+
const _: () = assert!(size_of::<Xp>() == size_of::<u16>());
50+
const _: () = assert!(align_of::<Xp>() == align_of::<u16>());
51+
52+
/// Number of lanes in the SIMD vector
53+
const LANES: usize = 32; // up to AVX512
54+
55+
let compose = table.field_unchecked::<Compose>(0);
56+
let compose = compose.first().unwrap();
57+
58+
let net = table.field_unchecked::<NetworkStreamRef>(1);
59+
let net = net.get(..).unwrap();
60+
61+
let mut prev_xp = table.field_unchecked::<Xp>(2);
62+
let prev_xp = prev_xp.get_mut(..).unwrap();
63+
let prev_xp: &mut [u16] =
64+
core::slice::from_raw_parts_mut(prev_xp.as_mut_ptr().cast(), count);
65+
66+
let mut xp = table.field_unchecked::<Xp>(3);
67+
let xp = xp.get_mut(..).unwrap();
68+
let xp: &mut [u16] =
69+
core::slice::from_raw_parts_mut(xp.as_mut_ptr().cast(), count);
70+
71+
simd_utils::copy_and_get_diff::<_, LANES>(
72+
prev_xp,
73+
xp,
74+
|idx, prev, current| {
75+
debug_assert!(prev != current);
76+
77+
let net = net.get(idx).unwrap();
78+
79+
let current = Xp::from(*current);
80+
let visual = current.get_visual();
81+
82+
let packet = play::ExperienceBarUpdateS2c {
83+
bar: visual.prop,
84+
level: VarInt(i32::from(visual.level)),
85+
total_xp: VarInt::default(),
86+
};
87+
88+
let entity = table.entity(idx);
89+
entity.modified::<Xp>();
90+
91+
compose
92+
.unicast(&packet, *net, SystemId(100), &world)
93+
.unwrap();
94+
},
95+
);
96+
}
4797
}
48-
49-
entity.modified::<Xp>();
50-
51-
let visual = current.get_visual();
52-
53-
let packet = play::ExperienceBarUpdateS2c {
54-
bar: visual.prop,
55-
level: VarInt(i32::from(visual.level)),
56-
total_xp: VarInt::default(),
57-
};
58-
59-
compose
60-
.unicast(&packet, *net, SystemId(100), &world)
61-
.unwrap();
62-
63-
*prev = *current;
6498
});
6599

66100
system!("entity_metadata_sync", world, &Compose($), &mut MetadataChanges)

crates/hyperion/src/lib.rs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#![feature(array_chunks)]
2424
#![feature(portable_simd)]
2525
#![feature(trivial_bounds)]
26+
#![feature(pointer_is_aligned_to)]
2627

2728
pub const NUM_THREADS: usize = 8;
2829
pub const CHUNK_HEIGHT_SPAN: u32 = 384; // 512; // usually 384
@@ -39,7 +40,10 @@ use std::{
3940
use anyhow::{Context, bail};
4041
use derive_more::{Deref, DerefMut};
4142
use egress::EgressModule;
42-
use flecs_ecs::prelude::*;
43+
use flecs_ecs::{
44+
prelude::*,
45+
sys::{ecs_os_get_api, ecs_os_set_api, ecs_os_set_api_defaults},
46+
};
4347
pub use glam;
4448
use glam::IVec2;
4549
use ingress::IngressModule;
@@ -197,19 +201,19 @@ impl Hyperion {
197201
.map_err(|_| anyhow::anyhow!("failed to create compression level"))?,
198202
});
199203

200-
// unsafe {
201-
// ecs_os_set_api_defaults();
202-
// let mut os_api = ecs_os_get_api();
203-
//
204-
// let (malloc, calloc, realloc, free) = alloc::setup_custom_allocators();
205-
//
206-
// os_api.malloc_ = malloc;
207-
// os_api.calloc_ = calloc;
208-
// os_api.realloc_ = realloc;
209-
// os_api.free_ = free;
210-
//
211-
// ecs_os_set_api(&mut os_api);
212-
// }
204+
unsafe {
205+
ecs_os_set_api_defaults();
206+
let mut os_api = ecs_os_get_api();
207+
208+
let (malloc, calloc, realloc, free) = alloc::setup_custom_allocators();
209+
210+
os_api.malloc_ = malloc;
211+
os_api.calloc_ = calloc;
212+
os_api.realloc_ = realloc;
213+
os_api.free_ = free;
214+
215+
ecs_os_set_api(&mut os_api);
216+
}
213217

214218
let world = World::new();
215219

0 commit comments

Comments
 (0)