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 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",
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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*);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue