Schedule wait lists of threads as a single event,
to save on events. Also, improve efficiency of event_s allocation. Add some event statistics to get an idea where performance is really going.
This commit is contained in:
parent
dedae73761
commit
aa3a6dba4e
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: event.cc,v 1.10 2002/08/12 01:35:08 steve Exp $"
|
#ident "$Id: event.cc,v 1.11 2003/01/06 23:57:26 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "event.h"
|
# include "event.h"
|
||||||
|
|
@ -189,6 +189,12 @@ void compile_named_event(char*label, char*name)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: event.cc,v $
|
* $Log: event.cc,v $
|
||||||
|
* Revision 1.11 2003/01/06 23:57:26 steve
|
||||||
|
* Schedule wait lists of threads as a single event,
|
||||||
|
* to save on events. Also, improve efficiency of
|
||||||
|
* event_s allocation. Add some event statistics to
|
||||||
|
* get an idea where performance is really going.
|
||||||
|
*
|
||||||
* Revision 1.10 2002/08/12 01:35:08 steve
|
* Revision 1.10 2002/08/12 01:35:08 steve
|
||||||
* conditional ident string using autoconfig.
|
* conditional ident string using autoconfig.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
19
vvp/main.cc
19
vvp/main.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: main.cc,v 1.31 2002/09/18 03:34:07 steve Exp $"
|
#ident "$Id: main.cc,v 1.32 2003/01/06 23:57:26 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -273,6 +273,17 @@ int main(int argc, char*argv[])
|
||||||
print_rusage(stderr, cycles+2, cycles+1);
|
print_rusage(stderr, cycles+2, cycles+1);
|
||||||
if (logfile && logfile != stderr)
|
if (logfile && logfile != stderr)
|
||||||
print_rusage(logfile, cycles+2, cycles+1);
|
print_rusage(logfile, cycles+2, cycles+1);
|
||||||
|
|
||||||
|
fprintf(stderr, "Event counts: (event pool = %lu)\n",
|
||||||
|
count_event_pool);
|
||||||
|
fprintf(stderr, " %8lu thread schedule events\n",
|
||||||
|
count_thread_events);
|
||||||
|
fprintf(stderr, " %8lu propagation events\n",
|
||||||
|
count_prop_events);
|
||||||
|
fprintf(stderr, " %8lu assign events\n",
|
||||||
|
count_assign_events);
|
||||||
|
fprintf(stderr, " %8lu other events\n",
|
||||||
|
count_gen_events);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -280,6 +291,12 @@ int main(int argc, char*argv[])
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: main.cc,v $
|
* $Log: main.cc,v $
|
||||||
|
* Revision 1.32 2003/01/06 23:57:26 steve
|
||||||
|
* Schedule wait lists of threads as a single event,
|
||||||
|
* to save on events. Also, improve efficiency of
|
||||||
|
* event_s allocation. Add some event statistics to
|
||||||
|
* get an idea where performance is really going.
|
||||||
|
*
|
||||||
* Revision 1.31 2002/09/18 03:34:07 steve
|
* Revision 1.31 2002/09/18 03:34:07 steve
|
||||||
* printf size warning.
|
* printf size warning.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: schedule.cc,v 1.20 2002/08/12 01:35:08 steve Exp $"
|
#ident "$Id: schedule.cc,v 1.21 2003/01/06 23:57:26 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "schedule.h"
|
# include "schedule.h"
|
||||||
|
|
@ -31,6 +31,13 @@
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
|
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The event queue is arranged as a skip list, with the simulation
|
* The event queue is arranged as a skip list, with the simulation
|
||||||
* time the key to the list. The simulation time is stored in each
|
* time the key to the list. The simulation time is stored in each
|
||||||
|
|
@ -60,6 +67,9 @@ struct event_s {
|
||||||
|
|
||||||
struct event_s*next;
|
struct event_s*next;
|
||||||
struct event_s*last;
|
struct event_s*last;
|
||||||
|
|
||||||
|
void* operator new (size_t);
|
||||||
|
void operator delete(void*obj, size_t s);
|
||||||
};
|
};
|
||||||
const unsigned TYPE_GEN = 0;
|
const unsigned TYPE_GEN = 0;
|
||||||
const unsigned TYPE_THREAD = 1;
|
const unsigned TYPE_THREAD = 1;
|
||||||
|
|
@ -72,25 +82,33 @@ const unsigned TYPE_ASSIGN = 3;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static struct event_s* free_list = 0;
|
static struct event_s* free_list = 0;
|
||||||
|
static const unsigned CHUNK_COUNT = 8192 / sizeof(struct event_s);
|
||||||
|
|
||||||
inline static struct event_s* e_alloc()
|
inline void* event_s::operator new (size_t size)
|
||||||
{
|
{
|
||||||
|
assert(size == sizeof(struct event_s));
|
||||||
|
|
||||||
struct event_s* cur = free_list;
|
struct event_s* cur = free_list;
|
||||||
if (!cur)
|
if (!cur) {
|
||||||
{
|
cur = (struct event_s*)
|
||||||
cur = (struct event_s*) malloc(sizeof(struct event_s));
|
malloc(CHUNK_COUNT * sizeof(struct event_s));
|
||||||
// cur = (struct event_s*) calloc(1, sizeof(struct event_s));
|
for (unsigned idx = 1 ; idx < CHUNK_COUNT ; idx += 1) {
|
||||||
|
cur[idx].next = free_list;
|
||||||
|
free_list = cur + idx;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
count_event_pool += CHUNK_COUNT;
|
||||||
|
|
||||||
|
} else {
|
||||||
free_list = cur->next;
|
free_list = cur->next;
|
||||||
// memset(cur, 0, sizeof(struct event_s));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static void e_free(struct event_s* cur)
|
inline void event_s::operator delete(void*obj, size_t size)
|
||||||
{
|
{
|
||||||
|
struct event_s*cur = reinterpret_cast<event_s*>(obj);
|
||||||
cur->next = free_list;
|
cur->next = free_list;
|
||||||
free_list = cur;
|
free_list = cur;
|
||||||
}
|
}
|
||||||
|
|
@ -246,7 +264,7 @@ static struct event_s* pull_sync_event(void)
|
||||||
|
|
||||||
void schedule_vthread(vthread_t thr, unsigned delay, bool push_flag)
|
void schedule_vthread(vthread_t thr, unsigned delay, bool push_flag)
|
||||||
{
|
{
|
||||||
struct event_s*cur = e_alloc();
|
struct event_s*cur = new event_s;
|
||||||
|
|
||||||
cur->delay = delay;
|
cur->delay = delay;
|
||||||
cur->thr = thr;
|
cur->thr = thr;
|
||||||
|
|
@ -267,7 +285,7 @@ void schedule_vthread(vthread_t thr, unsigned delay, bool push_flag)
|
||||||
|
|
||||||
void functor_s::schedule(unsigned delay)
|
void functor_s::schedule(unsigned delay)
|
||||||
{
|
{
|
||||||
struct event_s*cur = e_alloc();
|
struct event_s*cur = new event_s;
|
||||||
|
|
||||||
cur->delay = delay;
|
cur->delay = delay;
|
||||||
cur->funp = this;
|
cur->funp = this;
|
||||||
|
|
@ -280,7 +298,7 @@ void functor_s::schedule(unsigned delay)
|
||||||
|
|
||||||
void schedule_assign(vvp_ipoint_t fun, unsigned char val, unsigned delay)
|
void schedule_assign(vvp_ipoint_t fun, unsigned char val, unsigned delay)
|
||||||
{
|
{
|
||||||
struct event_s*cur = e_alloc();
|
struct event_s*cur = new event_s;
|
||||||
|
|
||||||
cur->delay = delay;
|
cur->delay = delay;
|
||||||
cur->fun = fun;
|
cur->fun = fun;
|
||||||
|
|
@ -292,7 +310,7 @@ void schedule_assign(vvp_ipoint_t fun, unsigned char val, unsigned delay)
|
||||||
|
|
||||||
void schedule_generic(vvp_gen_event_t obj, unsigned char val, unsigned delay)
|
void schedule_generic(vvp_gen_event_t obj, unsigned char val, unsigned delay)
|
||||||
{
|
{
|
||||||
struct event_s*cur = e_alloc();
|
struct event_s*cur = new event_s;
|
||||||
|
|
||||||
cur->delay = delay;
|
cur->delay = delay;
|
||||||
cur->obj = obj;
|
cur->obj = obj;
|
||||||
|
|
@ -339,7 +357,7 @@ void schedule_simulate(void)
|
||||||
assert(sync_cur->obj->sync_flag);
|
assert(sync_cur->obj->sync_flag);
|
||||||
sync_cur->obj->run(sync_cur->obj, sync_cur->val);
|
sync_cur->obj->run(sync_cur->obj, sync_cur->val);
|
||||||
}
|
}
|
||||||
e_free(sync_cur);
|
delete sync_cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -349,17 +367,20 @@ void schedule_simulate(void)
|
||||||
|
|
||||||
switch (cur->type) {
|
switch (cur->type) {
|
||||||
case TYPE_THREAD:
|
case TYPE_THREAD:
|
||||||
|
count_thread_events += 1;
|
||||||
vthread_run(cur->thr);
|
vthread_run(cur->thr);
|
||||||
e_free(cur);
|
delete cur;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_PROP:
|
case TYPE_PROP:
|
||||||
//printf("Propagate %p\n", cur->fun);
|
//printf("Propagate %p\n", cur->fun);
|
||||||
|
count_prop_events += 1;
|
||||||
cur->funp->propagate(false);
|
cur->funp->propagate(false);
|
||||||
e_free(cur);
|
delete(cur);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_ASSIGN:
|
case TYPE_ASSIGN:
|
||||||
|
count_assign_events += 1;
|
||||||
switch (cur->val) {
|
switch (cur->val) {
|
||||||
case 0:
|
case 0:
|
||||||
functor_set(cur->fun, cur->val, St0, false);
|
functor_set(cur->fun, cur->val, St0, false);
|
||||||
|
|
@ -374,14 +395,15 @@ void schedule_simulate(void)
|
||||||
functor_set(cur->fun, cur->val, HiZ, false);
|
functor_set(cur->fun, cur->val, HiZ, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
e_free(cur);
|
delete(cur);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_GEN:
|
case TYPE_GEN:
|
||||||
|
count_gen_events += 1;
|
||||||
if (cur->obj && cur->obj->run) {
|
if (cur->obj && cur->obj->run) {
|
||||||
if (cur->obj->sync_flag == false) {
|
if (cur->obj->sync_flag == false) {
|
||||||
cur->obj->run(cur->obj, cur->val);
|
cur->obj->run(cur->obj, cur->val);
|
||||||
e_free(cur);
|
delete (cur);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
postpone_sync_event(cur);
|
postpone_sync_event(cur);
|
||||||
|
|
@ -405,7 +427,7 @@ void schedule_simulate(void)
|
||||||
sync_cur->obj->run(sync_cur->obj, sync_cur->val);
|
sync_cur->obj->run(sync_cur->obj, sync_cur->val);
|
||||||
}
|
}
|
||||||
|
|
||||||
e_free(sync_cur);
|
delete (sync_cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -415,6 +437,12 @@ void schedule_simulate(void)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: schedule.cc,v $
|
* $Log: schedule.cc,v $
|
||||||
|
* Revision 1.21 2003/01/06 23:57:26 steve
|
||||||
|
* Schedule wait lists of threads as a single event,
|
||||||
|
* to save on events. Also, improve efficiency of
|
||||||
|
* event_s allocation. Add some event statistics to
|
||||||
|
* get an idea where performance is really going.
|
||||||
|
*
|
||||||
* Revision 1.20 2002/08/12 01:35:08 steve
|
* Revision 1.20 2002/08/12 01:35:08 steve
|
||||||
* conditional ident string using autoconfig.
|
* conditional ident string using autoconfig.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: schedule.h,v 1.11 2002/08/12 01:35:08 steve Exp $"
|
#ident "$Id: schedule.h,v 1.12 2003/01/06 23:57:26 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "vthread.h"
|
# include "vthread.h"
|
||||||
|
|
@ -90,9 +90,23 @@ extern vvp_time64_t schedule_simtime(void);
|
||||||
extern void schedule_finish(int rc);
|
extern void schedule_finish(int rc);
|
||||||
extern bool schedule_finished(void);
|
extern bool schedule_finished(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are event counters for the sake of performance measurements.
|
||||||
|
*/
|
||||||
|
extern unsigned long count_assign_events;
|
||||||
|
extern unsigned long count_gen_events;
|
||||||
|
extern unsigned long count_prop_events;
|
||||||
|
extern unsigned long count_thread_events;
|
||||||
|
extern unsigned long count_event_pool;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: schedule.h,v $
|
* $Log: schedule.h,v $
|
||||||
|
* Revision 1.12 2003/01/06 23:57:26 steve
|
||||||
|
* Schedule wait lists of threads as a single event,
|
||||||
|
* to save on events. Also, improve efficiency of
|
||||||
|
* event_s allocation. Add some event statistics to
|
||||||
|
* get an idea where performance is really going.
|
||||||
|
*
|
||||||
* Revision 1.11 2002/08/12 01:35:08 steve
|
* Revision 1.11 2002/08/12 01:35:08 steve
|
||||||
* conditional ident string using autoconfig.
|
* conditional ident string using autoconfig.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: vthread.cc,v 1.95 2002/11/22 00:01:50 steve Exp $"
|
#ident "$Id: vthread.cc,v 1.96 2003/01/06 23:57:26 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "vthread.h"
|
# include "vthread.h"
|
||||||
|
|
@ -290,16 +290,24 @@ static void vthread_reap(vthread_t thr)
|
||||||
|
|
||||||
void vthread_mark_scheduled(vthread_t thr)
|
void vthread_mark_scheduled(vthread_t thr)
|
||||||
{
|
{
|
||||||
|
while (thr != 0) {
|
||||||
assert(thr->is_scheduled == 0);
|
assert(thr->is_scheduled == 0);
|
||||||
thr->is_scheduled = 1;
|
thr->is_scheduled = 1;
|
||||||
|
thr = thr->wait_next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function runs a thread by fetching an instruction,
|
* This function runs each thread by fetching an instruction,
|
||||||
* incrementing the PC, and executing the instruction.
|
* incrementing the PC, and executing the instruction. The thread may
|
||||||
|
* be the head of a list, so each thread is run so far as possible.
|
||||||
*/
|
*/
|
||||||
void vthread_run(vthread_t thr)
|
void vthread_run(vthread_t thr)
|
||||||
{
|
{
|
||||||
|
while (thr != 0) {
|
||||||
|
vthread_t tmp = thr->wait_next;
|
||||||
|
thr->wait_next = 0;
|
||||||
|
|
||||||
assert(thr->is_scheduled);
|
assert(thr->is_scheduled);
|
||||||
thr->is_scheduled = 0;
|
thr->is_scheduled = 0;
|
||||||
|
|
||||||
|
|
@ -315,7 +323,10 @@ void vthread_run(vthread_t thr)
|
||||||
be paused, so break out of the loop. */
|
be paused, so break out of the loop. */
|
||||||
bool rc = (cp->opcode)(thr, cp);
|
bool rc = (cp->opcode)(thr, cp);
|
||||||
if (rc == false)
|
if (rc == false)
|
||||||
return;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
thr = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -326,14 +337,12 @@ void vthread_run(vthread_t thr)
|
||||||
*/
|
*/
|
||||||
void vthread_schedule_list(vthread_t thr)
|
void vthread_schedule_list(vthread_t thr)
|
||||||
{
|
{
|
||||||
while (thr) {
|
for (vthread_t cur = thr ; cur ; cur = cur->wait_next) {
|
||||||
vthread_t tmp = thr;
|
assert(cur->waiting_for_event);
|
||||||
thr = thr->wait_next;
|
cur->waiting_for_event = 0;
|
||||||
assert(tmp->waiting_for_event);
|
|
||||||
tmp->waiting_for_event = 0;
|
|
||||||
tmp->wait_next = 0;
|
|
||||||
schedule_vthread(tmp, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
schedule_vthread(thr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2496,6 +2505,12 @@ bool of_CALL_UFUNC(vthread_t thr, vvp_code_t cp)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vthread.cc,v $
|
* $Log: vthread.cc,v $
|
||||||
|
* Revision 1.96 2003/01/06 23:57:26 steve
|
||||||
|
* Schedule wait lists of threads as a single event,
|
||||||
|
* to save on events. Also, improve efficiency of
|
||||||
|
* event_s allocation. Add some event statistics to
|
||||||
|
* get an idea where performance is really going.
|
||||||
|
*
|
||||||
* Revision 1.95 2002/11/22 00:01:50 steve
|
* Revision 1.95 2002/11/22 00:01:50 steve
|
||||||
* Careful of left operands to shift that are constant.
|
* Careful of left operands to shift that are constant.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue