forked from libre-chip/fayalite
speed up simulation by optimizing SimulationImpl::read_traces
this makes cpu/crates/cpu/tests/next_pc.rs take 56s instead of 168s
This commit is contained in:
parent
1bc835803b
commit
c632e5d570
3 changed files with 46 additions and 9 deletions
|
|
@ -40,7 +40,7 @@ use crate::{
|
||||||
OpaqueSimValue, OpaqueSimValueSize, OpaqueSimValueSizeRange, OpaqueSimValueSlice,
|
OpaqueSimValue, OpaqueSimValueSize, OpaqueSimValueSizeRange, OpaqueSimValueSlice,
|
||||||
OpaqueSimValueWriter,
|
OpaqueSimValueWriter,
|
||||||
},
|
},
|
||||||
util::{BitSliceWriteWithBase, DebugAsDisplay, HashMap, HashSet},
|
util::{BitSliceWriteWithBase, DebugAsDisplay, HashMap, HashSet, copy_le_bytes_to_bitslice},
|
||||||
};
|
};
|
||||||
use bitvec::{bits, order::Lsb0, slice::BitSlice, vec::BitVec, view::BitView};
|
use bitvec::{bits, order::Lsb0, slice::BitSlice, vec::BitVec, view::BitView};
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
|
|
@ -2198,14 +2198,11 @@ impl SimulationImpl {
|
||||||
SimTraceKind::BigUInt { index, ty: _ } | SimTraceKind::BigSInt { index, ty: _ } => {
|
SimTraceKind::BigUInt { index, ty: _ } | SimTraceKind::BigSInt { index, ty: _ } => {
|
||||||
let state = state.unwrap_bits_mut();
|
let state = state.unwrap_bits_mut();
|
||||||
let bigint = &self.state.big_slots[index];
|
let bigint = &self.state.big_slots[index];
|
||||||
let mut bytes = bigint.to_signed_bytes_le();
|
copy_le_bytes_to_bitslice(
|
||||||
bytes.resize(
|
state,
|
||||||
state.len().div_ceil(8),
|
&bigint.to_signed_bytes_le(),
|
||||||
if bigint.is_negative() { 0xFF } else { 0 },
|
bigint.is_negative(),
|
||||||
);
|
);
|
||||||
let bitslice = BitSlice::<u8, Lsb0>::from_slice(&bytes);
|
|
||||||
let bitslice = &bitslice[..state.len()];
|
|
||||||
state.clone_from_bitslice(bitslice);
|
|
||||||
}
|
}
|
||||||
SimTraceKind::BigBool { index }
|
SimTraceKind::BigBool { index }
|
||||||
| SimTraceKind::BigAsyncReset { index }
|
| SimTraceKind::BigAsyncReset { index }
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ pub use misc::{
|
||||||
os_str_strip_suffix, serialize_to_json_ascii, serialize_to_json_ascii_pretty,
|
os_str_strip_suffix, serialize_to_json_ascii, serialize_to_json_ascii_pretty,
|
||||||
serialize_to_json_ascii_pretty_with_indent, slice_range, try_slice_range,
|
serialize_to_json_ascii_pretty_with_indent, slice_range, try_slice_range,
|
||||||
};
|
};
|
||||||
pub(crate) use misc::{InternedStrCompareAsStr, chain};
|
pub(crate) use misc::{InternedStrCompareAsStr, chain, copy_le_bytes_to_bitslice};
|
||||||
|
|
||||||
pub mod job_server;
|
pub mod job_server;
|
||||||
pub mod prefix_sum;
|
pub mod prefix_sum;
|
||||||
|
|
|
||||||
|
|
@ -612,3 +612,43 @@ impl std::borrow::Borrow<str> for InternedStrCompareAsStr {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn copy_le_bytes_to_bitslice(
|
||||||
|
dest: &mut BitSlice<usize, Lsb0>,
|
||||||
|
bytes: &[u8],
|
||||||
|
msb_fill: bool,
|
||||||
|
) {
|
||||||
|
let (chunks, remainder) = bytes.as_chunks();
|
||||||
|
let mut filled_to = 0;
|
||||||
|
for (i, chunk) in chunks.iter().enumerate() {
|
||||||
|
if let Some(start_bit_index) = i.checked_mul(usize::BITS as usize)
|
||||||
|
&& start_bit_index < dest.len()
|
||||||
|
{
|
||||||
|
let end_bit_index = start_bit_index
|
||||||
|
.saturating_add(usize::BITS as usize)
|
||||||
|
.min(dest.len());
|
||||||
|
let bit_len = end_bit_index - start_bit_index;
|
||||||
|
let chunk = usize::from_le_bytes(*chunk);
|
||||||
|
dest[start_bit_index..end_bit_index].copy_from_bitslice(&chunk.view_bits()[..bit_len]);
|
||||||
|
filled_to = end_bit_index;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !remainder.is_empty() {
|
||||||
|
if let Some(start_bit_index) = chunks.len().checked_mul(usize::BITS as usize)
|
||||||
|
&& start_bit_index < dest.len()
|
||||||
|
{
|
||||||
|
let end_bit_index = start_bit_index
|
||||||
|
.saturating_add(usize::BITS as usize)
|
||||||
|
.min(dest.len());
|
||||||
|
let bit_len = end_bit_index - start_bit_index;
|
||||||
|
let mut chunk = [if msb_fill { !0 } else { 0 }; _];
|
||||||
|
chunk[..remainder.len()].copy_from_slice(remainder);
|
||||||
|
let chunk = usize::from_le_bytes(chunk);
|
||||||
|
dest[start_bit_index..end_bit_index].copy_from_bitslice(&chunk.view_bits()[..bit_len]);
|
||||||
|
filled_to = end_bit_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dest[filled_to..].fill(msb_fill);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue