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,
|
||||
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 num_bigint::BigInt;
|
||||
|
|
@ -2198,14 +2198,11 @@ impl SimulationImpl {
|
|||
SimTraceKind::BigUInt { index, ty: _ } | SimTraceKind::BigSInt { index, ty: _ } => {
|
||||
let state = state.unwrap_bits_mut();
|
||||
let bigint = &self.state.big_slots[index];
|
||||
let mut bytes = bigint.to_signed_bytes_le();
|
||||
bytes.resize(
|
||||
state.len().div_ceil(8),
|
||||
if bigint.is_negative() { 0xFF } else { 0 },
|
||||
copy_le_bytes_to_bitslice(
|
||||
state,
|
||||
&bigint.to_signed_bytes_le(),
|
||||
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::BigAsyncReset { index }
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ pub use misc::{
|
|||
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,
|
||||
};
|
||||
pub(crate) use misc::{InternedStrCompareAsStr, chain};
|
||||
pub(crate) use misc::{InternedStrCompareAsStr, chain, copy_le_bytes_to_bitslice};
|
||||
|
||||
pub mod job_server;
|
||||
pub mod prefix_sum;
|
||||
|
|
|
|||
|
|
@ -612,3 +612,43 @@ impl std::borrow::Borrow<str> for InternedStrCompareAsStr {
|
|||
&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