ASSIGN transfer data to scheduler efficiently/permalloc vvp_net_t objects.
The vvp_net_t objects are never deleted, so overload the new operator
to do a more space efficient permanent allocation.
The %assign/v instruction copied the vvp_vector4_t object needlessly
on its way to the scheduler. Eliminate that duplication.(cherry picked from commit d0f303463d)
This commit is contained in:
parent
2e9970a98c
commit
3c4346acb2
11
vvp/main.cc
11
vvp/main.cc
|
|
@ -279,9 +279,11 @@ int main(int argc, char*argv[])
|
|||
vpi_mcd_printf(1, " %8lu bufif\n", count_functors_bufif);
|
||||
vpi_mcd_printf(1, " %8lu resolv\n",count_functors_resolv);
|
||||
vpi_mcd_printf(1, " %8lu signals\n", count_functors_sig);
|
||||
vpi_mcd_printf(1, " ... %8lu opcodes (%lu bytes)\n",
|
||||
vpi_mcd_printf(1, " ... %8lu opcodes (%zu bytes)\n",
|
||||
count_opcodes, (unsigned long)size_opcodes);
|
||||
vpi_mcd_printf(1, " ... %8lu nets\n", count_vpi_nets);
|
||||
vpi_mcd_printf(1, " ... %8lu vvp_nets (%zu bytes)\n",
|
||||
count_vvp_nets, size_vvp_nets);
|
||||
vpi_mcd_printf(1, " ... %8lu memories\n", count_vpi_memories);
|
||||
vpi_mcd_printf(1, " ... %8lu scopes\n", count_vpi_scopes);
|
||||
}
|
||||
|
|
@ -299,12 +301,11 @@ int main(int argc, char*argv[])
|
|||
my_getrusage(cycles+2);
|
||||
print_rusage(cycles+2, cycles+1);
|
||||
|
||||
vpi_mcd_printf(1, "Event counts: (event pool = %lu)\n",
|
||||
count_event_pool);
|
||||
vpi_mcd_printf(1, "Event counts:\n");
|
||||
vpi_mcd_printf(1, " %8lu time steps (pool=%lu)\n",
|
||||
count_time_events, count_time_pool);
|
||||
vpi_mcd_printf(1, " %8lu thread schedule events\n",
|
||||
count_thread_events);
|
||||
vpi_mcd_printf(1, " %8lu propagation events\n",
|
||||
count_prop_events);
|
||||
vpi_mcd_printf(1, " %8lu assign events\n",
|
||||
count_assign_events);
|
||||
vpi_mcd_printf(1, " %8lu other events\n",
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@
|
|||
|
||||
unsigned long count_assign_events = 0;
|
||||
unsigned long count_gen_events = 0;
|
||||
unsigned long count_prop_events = 0;
|
||||
unsigned long count_thread_events = 0;
|
||||
unsigned long count_event_pool = 0;
|
||||
// Count the time events (A time cell created)
|
||||
unsigned long count_time_events = 0;
|
||||
unsigned long count_time_pool = 0;
|
||||
|
||||
|
||||
|
|
@ -96,6 +96,12 @@ void del_thr_event_s::run_run(void)
|
|||
}
|
||||
|
||||
struct assign_vector4_event_s : public event_s {
|
||||
/* The default constructor. */
|
||||
assign_vector4_event_s() { }
|
||||
/* A constructor that makes the val directly. */
|
||||
assign_vector4_event_s(const vvp_vector4_t&that, unsigned adr, unsigned wid)
|
||||
: val(that,adr,wid) { }
|
||||
|
||||
/* Where to do the assign. */
|
||||
vvp_net_ptr_t ptr;
|
||||
/* Value to assign. */
|
||||
|
|
@ -485,6 +491,19 @@ void schedule_assign_vector(vvp_net_ptr_t ptr,
|
|||
schedule_event_(cur, delay, SEQ_NBASSIGN);
|
||||
}
|
||||
|
||||
void schedule_assign_plucked_vector(vvp_net_ptr_t ptr,
|
||||
vvp_time64_t delay,
|
||||
const vvp_vector4_t&src,
|
||||
unsigned adr, unsigned wid)
|
||||
{
|
||||
struct assign_vector4_event_s*cur
|
||||
= new struct assign_vector4_event_s(src,adr,wid);
|
||||
cur->ptr = ptr;
|
||||
cur->vwid = 0;
|
||||
cur->base = 0;
|
||||
schedule_event_(cur, delay, SEQ_NBASSIGN);
|
||||
}
|
||||
|
||||
void schedule_assign_array_word(vvp_array_t mem,
|
||||
unsigned word_addr,
|
||||
unsigned off,
|
||||
|
|
|
|||
|
|
@ -50,6 +50,10 @@ extern void schedule_assign_vector(vvp_net_ptr_t ptr,
|
|||
extern void schedule_assign_vector(vvp_net_ptr_t ptr,
|
||||
const vvp_vector4_t&val,
|
||||
vvp_time64_t delay);
|
||||
extern void schedule_assign_plucked_vector(vvp_net_ptr_t ptr,
|
||||
vvp_time64_t delay,
|
||||
const vvp_vector4_t&val,
|
||||
unsigned adr, unsigned wid);
|
||||
|
||||
extern void schedule_assign_array_word(vvp_array_t mem,
|
||||
unsigned word_address,
|
||||
|
|
|
|||
|
|
@ -27,10 +27,15 @@ extern unsigned long count_functors_logic;
|
|||
extern unsigned long count_functors_bufif;
|
||||
extern unsigned long count_functors_resolv;
|
||||
extern unsigned long count_functors_sig;
|
||||
extern unsigned long count_vvp_nets;
|
||||
extern unsigned long count_vpi_nets;
|
||||
extern unsigned long count_vpi_scopes;
|
||||
extern unsigned long count_vpi_memories;
|
||||
|
||||
extern unsigned long count_time_events;
|
||||
extern unsigned long count_time_pool;
|
||||
|
||||
extern size_t size_opcodes;
|
||||
extern size_t size_vvp_nets;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -700,10 +700,15 @@ bool of_ASSIGN_V0(vthread_t thr, vvp_code_t cp)
|
|||
unsigned delay = cp->bit_idx[0];
|
||||
unsigned bit = cp->bit_idx[1];
|
||||
|
||||
vvp_vector4_t value = vthread_bits_to_vector(thr, bit, wid);
|
||||
|
||||
vvp_net_ptr_t ptr (cp->net, 0);
|
||||
schedule_assign_vector(ptr, value, delay);
|
||||
if (bit >= 4) {
|
||||
// If the vector is not a synthetic one, then have the
|
||||
// scheduler pluck it direcly out of my vector space.
|
||||
schedule_assign_plucked_vector(ptr, delay, thr->bits4, bit, wid);
|
||||
} else {
|
||||
vvp_vector4_t value = vthread_bits_to_vector(thr, bit, wid);
|
||||
schedule_assign_vector(ptr, value, delay);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -721,10 +726,14 @@ bool of_ASSIGN_V0D(vthread_t thr, vvp_code_t cp)
|
|||
unsigned long delay = thr->words[cp->bit_idx[0]].w_int;
|
||||
unsigned bit = cp->bit_idx[1];
|
||||
|
||||
vvp_vector4_t value = vthread_bits_to_vector(thr, bit, wid);
|
||||
|
||||
vvp_net_ptr_t ptr (cp->net, 0);
|
||||
schedule_assign_vector(ptr, value, delay);
|
||||
|
||||
if (bit >= 4) {
|
||||
schedule_assign_plucked_vector(ptr, delay, thr->bits4, bit, wid);
|
||||
} else {
|
||||
vvp_vector4_t value = vthread_bits_to_vector(thr, bit, wid);
|
||||
schedule_assign_vector(ptr, value, delay);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,31 @@
|
|||
# include <math.h>
|
||||
# include <assert.h>
|
||||
|
||||
// Allocate around 1Megbytes/chunk.
|
||||
static const size_t VVP_NET_CHUNK = 1024*1024/sizeof(vvp_net_t);
|
||||
static vvp_net_t*vvp_net_alloc_table = 0;
|
||||
static size_t vvp_net_alloc_remaining = 0;
|
||||
// For statistics, count the vvp_nets allocated and the bytes of alloc
|
||||
// chunks allocated.
|
||||
unsigned long count_vvp_nets = 0;
|
||||
size_t size_vvp_nets = 0;
|
||||
|
||||
void* vvp_net_t::operator new (size_t size)
|
||||
{
|
||||
assert(size == sizeof(vvp_net_t));
|
||||
if (vvp_net_alloc_remaining == 0) {
|
||||
vvp_net_alloc_table = ::new vvp_net_t[VVP_NET_CHUNK];
|
||||
vvp_net_alloc_remaining = VVP_NET_CHUNK;
|
||||
size_vvp_nets += size*VVP_NET_CHUNK;
|
||||
}
|
||||
|
||||
vvp_net_t*return_this = vvp_net_alloc_table;
|
||||
vvp_net_alloc_table += 1;
|
||||
vvp_net_alloc_remaining -= 1;
|
||||
count_vvp_nets += 1;
|
||||
return return_this;
|
||||
}
|
||||
|
||||
/* *** BIT operations *** */
|
||||
vvp_bit4_t add_with_carry(vvp_bit4_t a, vvp_bit4_t b, vvp_bit4_t&c)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -760,6 +760,13 @@ struct vvp_net_t {
|
|||
vvp_net_ptr_t port[4];
|
||||
vvp_net_ptr_t out;
|
||||
vvp_net_fun_t*fun;
|
||||
|
||||
public: // Need a better new for these objects.
|
||||
static void* operator new(std::size_t size);
|
||||
static void operator delete(void*); // not implemented
|
||||
private: // not implemented
|
||||
static void* operator new[](std::size_t size);
|
||||
static void operator delete[](void*);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue