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:
steve 2003-01-06 23:57:26 +00:00
parent dedae73761
commit aa3a6dba4e
5 changed files with 136 additions and 56 deletions

View File

@ -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.
* *

View File

@ -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.
* *

View File

@ -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.
* *

View File

@ -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.
* *

View File

@ -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.
* *