Skip to content

Commit

Permalink
Optimize node layoutand improve connection branch predition
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul1365972 committed Jan 13, 2024
1 parent d123bf1 commit bbf2714
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 11 deletions.
8 changes: 7 additions & 1 deletion crates/core/src/redpiler/backend/direct/compile.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::redpiler::backend::direct::node::NonMaxU8;
use crate::redpiler::compile_graph::{CompileGraph, LinkType, NodeIdx};
use crate::redpiler::{CompilerOptions, TaskMonitor};
use itertools::Itertools;
use mchprs_blocks::blocks::Block;
use mchprs_world::TickEntry;
use petgraph::visit::EdgeRef;
Expand Down Expand Up @@ -68,6 +70,10 @@ fn compile_node(
let updates = if node.ty != CNodeType::Constant {
graph
.edges_directed(node_idx, Direction::Outgoing)
.sorted_by_key(|edge| nodes_map[&edge.target()])
.into_group_map_by(|edge| std::mem::discriminant(&graph[edge.target()].ty))
.into_values()
.flatten()
.map(|edge| unsafe {
let idx = edge.target();
let idx = nodes_map[&idx];
Expand Down Expand Up @@ -99,7 +105,7 @@ fn compile_node(
facing_diode,
} => NodeType::Comparator {
mode: *mode,
far_input: *far_input,
far_input: far_input.map(|value| NonMaxU8::new(value).unwrap()),
facing_diode: *facing_diode,
},
CNodeType::Lamp => NodeType::Lamp,
Expand Down
21 changes: 16 additions & 5 deletions crates/core/src/redpiler/backend/direct/node.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use mchprs_blocks::blocks::ComparatorMode;
use smallvec::SmallVec;
use std::num::NonZeroU8;
use std::ops::{Index, IndexMut};

#[derive(Debug, Copy, Clone)]
Expand Down Expand Up @@ -114,7 +115,7 @@ pub enum NodeType {
Torch,
Comparator {
mode: ComparatorMode,
far_input: Option<u8>,
far_input: Option<NonMaxU8>,
facing_diode: bool,
},
Lamp,
Expand All @@ -132,15 +133,25 @@ pub struct NodeInput {
pub ss_counts: [u8; 16],
}

// struct is 128 bytes to fit nicely into cachelines
// which are usualy 64 bytes, it can vary but is almost always a power of 2
#[derive(Debug, Clone, Copy)]
pub struct NonMaxU8(NonZeroU8);

impl NonMaxU8 {
pub fn new(value: u8) -> Option<Self> {
NonZeroU8::new(value + 1).map(|x| Self(x))
}

pub fn get(self) -> u8 {
self.0.get() - 1
}
}

#[derive(Debug, Clone)]
#[repr(align(128))]
pub struct Node {
pub ty: NodeType,
pub default_inputs: NodeInput,
pub side_inputs: NodeInput,
pub updates: SmallVec<[ForwardLink; 18]>,
pub updates: SmallVec<[ForwardLink; 10]>,
pub is_io: bool,

/// Powered or lit
Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/redpiler/backend/direct/tick.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl DirectBackend {
let (mut input_power, side_input_power) = get_all_input(node);
if let Some(far_override) = far_input {
if input_power < 15 {
input_power = far_override;
input_power = far_override.get();
}
}
let old_strength = node.output_power;
Expand Down
7 changes: 3 additions & 4 deletions crates/core/src/redpiler/backend/direct/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@ pub(super) fn update_node(scheduler: &mut TickScheduler, node: &mut Node, node_i
if node.pending_tick {
return;
}
let should_be_off = get_bool_input(node);
let lit = node.powered;
if lit == should_be_off {
let should_be_powered = !get_bool_input(node);
if node.powered != should_be_powered {
schedule_tick(scheduler, node_id, node, 1, TickPriority::Normal);
}
}
Expand All @@ -51,7 +50,7 @@ pub(super) fn update_node(scheduler: &mut TickScheduler, node: &mut Node, node_i
let (mut input_power, side_input_power) = get_all_input(node);
if let Some(far_override) = far_input {
if input_power < 15 {
input_power = far_override;
input_power = far_override.get();
}
}
let old_strength = node.output_power;
Expand Down

0 comments on commit bbf2714

Please sign in to comment.