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:
Stephen Williams 2008-06-06 19:50:44 -07:00
parent 2e9970a98c
commit 3c4346acb2
7 changed files with 83 additions and 13 deletions

View File

@ -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 bufif\n", count_functors_bufif);
vpi_mcd_printf(1, " %8lu resolv\n",count_functors_resolv); 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 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); count_opcodes, (unsigned long)size_opcodes);
vpi_mcd_printf(1, " ... %8lu nets\n", count_vpi_nets); 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 memories\n", count_vpi_memories);
vpi_mcd_printf(1, " ... %8lu scopes\n", count_vpi_scopes); vpi_mcd_printf(1, " ... %8lu scopes\n", count_vpi_scopes);
} }
@ -299,12 +301,11 @@ int main(int argc, char*argv[])
my_getrusage(cycles+2); my_getrusage(cycles+2);
print_rusage(cycles+2, cycles+1); print_rusage(cycles+2, cycles+1);
vpi_mcd_printf(1, "Event counts: (event pool = %lu)\n", vpi_mcd_printf(1, "Event counts:\n");
count_event_pool); 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", vpi_mcd_printf(1, " %8lu thread schedule events\n",
count_thread_events); count_thread_events);
vpi_mcd_printf(1, " %8lu propagation events\n",
count_prop_events);
vpi_mcd_printf(1, " %8lu assign events\n", vpi_mcd_printf(1, " %8lu assign events\n",
count_assign_events); count_assign_events);
vpi_mcd_printf(1, " %8lu other events\n", vpi_mcd_printf(1, " %8lu other events\n",

View File

@ -30,9 +30,9 @@
unsigned long count_assign_events = 0; unsigned long count_assign_events = 0;
unsigned long count_gen_events = 0; unsigned long count_gen_events = 0;
unsigned long count_prop_events = 0;
unsigned long count_thread_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; 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 { 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. */ /* Where to do the assign. */
vvp_net_ptr_t ptr; vvp_net_ptr_t ptr;
/* Value to assign. */ /* Value to assign. */
@ -485,6 +491,19 @@ void schedule_assign_vector(vvp_net_ptr_t ptr,
schedule_event_(cur, delay, SEQ_NBASSIGN); 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, void schedule_assign_array_word(vvp_array_t mem,
unsigned word_addr, unsigned word_addr,
unsigned off, unsigned off,

View File

@ -50,6 +50,10 @@ extern void schedule_assign_vector(vvp_net_ptr_t ptr,
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, const vvp_vector4_t&val,
vvp_time64_t delay); 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, extern void schedule_assign_array_word(vvp_array_t mem,
unsigned word_address, unsigned word_address,

View File

@ -27,10 +27,15 @@ extern unsigned long count_functors_logic;
extern unsigned long count_functors_bufif; extern unsigned long count_functors_bufif;
extern unsigned long count_functors_resolv; extern unsigned long count_functors_resolv;
extern unsigned long count_functors_sig; extern unsigned long count_functors_sig;
extern unsigned long count_vvp_nets;
extern unsigned long count_vpi_nets; extern unsigned long count_vpi_nets;
extern unsigned long count_vpi_scopes; extern unsigned long count_vpi_scopes;
extern unsigned long count_vpi_memories; 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_opcodes;
extern size_t size_vvp_nets;
#endif #endif

View File

@ -700,10 +700,15 @@ bool of_ASSIGN_V0(vthread_t thr, vvp_code_t cp)
unsigned delay = cp->bit_idx[0]; unsigned delay = cp->bit_idx[0];
unsigned bit = cp->bit_idx[1]; 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); 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; 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 long delay = thr->words[cp->bit_idx[0]].w_int;
unsigned bit = cp->bit_idx[1]; 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); 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; return true;
} }

View File

@ -30,6 +30,31 @@
# include <math.h> # include <math.h>
# include <assert.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 *** */ /* *** BIT operations *** */
vvp_bit4_t add_with_carry(vvp_bit4_t a, vvp_bit4_t b, vvp_bit4_t&c) vvp_bit4_t add_with_carry(vvp_bit4_t a, vvp_bit4_t b, vvp_bit4_t&c)
{ {

View File

@ -760,6 +760,13 @@ struct vvp_net_t {
vvp_net_ptr_t port[4]; vvp_net_ptr_t port[4];
vvp_net_ptr_t out; vvp_net_ptr_t out;
vvp_net_fun_t*fun; 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*);
}; };
/* /*