diff --git a/examples/main.c b/examples/main.c index d15bbfb0d0c28cb80540e86d36a185aabb1ece38..680123987daa566e7070a0c319c3afc189cc4bbd 100644 --- a/examples/main.c +++ b/examples/main.c @@ -85,6 +85,7 @@ int main(int argc, char *argv[]) { int nr_nodes = 1, myrank = 0, grid[3] = {1, 1, 1}; FILE *file_thread; int with_outputs = 1; + int queue_search_window = 8; /* Choke on FP-exceptions. */ // feenableexcept( FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW ); @@ -135,7 +136,7 @@ int main(int argc, char *argv[]) { bzero(&s, sizeof(struct space)); /* Parse the options */ - while ((c = getopt(argc, argv, "a:c:d:f:g:m:q:r:s:t:w:y:z:")) != -1) + while ((c = getopt(argc, argv, "a:c:d:f:g:m:o:q:r:s:t:v:w:y:z:")) != -1) switch (c) { case 'a': if (sscanf(optarg, "%lf", &scaling) != 1) @@ -193,6 +194,12 @@ int main(int argc, char *argv[]) { error("Error parsing sub size."); if (myrank == 0) message("sub size set to %i.", space_subsize); break; + case 'v': + if (sscanf(optarg, "%d", &queue_search_window) != 1) + error("Error parsing sub size."); + if (myrank == 0) message("task overlap search window set to %i.", + queue_search_window); + break; case 'y': if(sscanf(optarg, "%d", &dump_tasks) != 1) error("Error parsing dump_tasks (-y)"); @@ -335,7 +342,7 @@ int main(int argc, char *argv[]) { tic = getticks(); if (myrank == 0) message("nr_nodes is %i.", nr_nodes); engine_init(&e, &s, dt_max, nr_threads, nr_queues, nr_nodes, myrank, - ENGINE_POLICY | engine_policy_steal); + ENGINE_POLICY | engine_policy_steal, queue_search_window); if (myrank == 0) message("engine_init took %.3f ms.", ((double)(getticks() - tic)) / CPU_TPS * 1000); diff --git a/src/engine.c b/src/engine.c index 054e9c8a64585c602c08ef2d4aae2ecccf21aa21..108875ae4a42265ebccbd6ad88972d4060c1c2a8 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2150,10 +2150,13 @@ static bool hyperthreads_present(void) { * @param nr_nodes The number of MPI ranks * @param nodeID The MPI rank of this node * @param policy The queuing policy to use. + * @param queue_search_window the search window for overlapping tasks. */ void engine_init(struct engine *e, struct space *s, float dt, int nr_threads, - int nr_queues, int nr_nodes, int nodeID, int policy) { + int nr_queues, int nr_nodes, int nodeID, int policy, + int queue_search_window) { + int i, k; float dt_min = dt; @@ -2237,6 +2240,7 @@ void engine_init(struct engine *e, struct space *s, float dt, int nr_threads, e->forcerepart = 0; e->links = NULL; e->nr_links = 0; + e->queue_search_window = queue_search_window; engine_rank = nodeID; /* Make the space link back to the engine. */ diff --git a/src/engine.h b/src/engine.h index 017455dc7da812f20703686e5d6b4715862546f1..ad580a641dd3830e0a0a6d39efeadfd847ba713a 100644 --- a/src/engine.h +++ b/src/engine.h @@ -54,6 +54,7 @@ #define engine_maxtaskspercell 128 #define engine_maxproxies 64 #define engine_tasksreweight 10 +#define engine_queue_search_window 8 #define engine_maxmetisweight 10000.0f @@ -134,6 +135,9 @@ struct engine { struct link *links; int nr_links, size_links; + /* Search window for overlapping tasks. */ + int queue_search_window; + #ifdef WITH_MPI /* MPI data type for the particle transfers */ MPI_Datatype part_mpi_type; @@ -144,7 +148,8 @@ struct engine { /* Function prototypes. */ void engine_barrier(struct engine *e, int tid); void engine_init(struct engine *e, struct space *s, float dt, int nr_threads, - int nr_queues, int nr_nodes, int nodeID, int policy); + int nr_queues, int nr_nodes, int nodeID, int policy, + int queue_search_window); void engine_launch(struct engine *e, int nr_runners, unsigned int mask); void engine_prepare(struct engine *e); void engine_step(struct engine *e); diff --git a/src/queue.c b/src/queue.c index af84c4b1f5e7e80fac05e5b122703fa718b7fead..51c03e7b76aa131d5a566b724595ae88dd3a405f 100644 --- a/src/queue.c +++ b/src/queue.c @@ -130,7 +130,8 @@ void queue_init(struct queue *q, struct task *tasks) { * @param blocking Block until access to the queue is granted. */ -struct task *queue_gettask(struct queue *q, const struct task *prev, int blocking) { +struct task *queue_gettask(struct queue *q, const struct task *prev, + int blocking, int queue_search_window) { lock_type *qlock = &q->lock; struct task *res = NULL; diff --git a/src/queue.h b/src/queue.h index 7f6d13c425f80cac20125bf422fe9da1ed06361f..aab43820eb9234a11409ca515822f1d39dfe40d0 100644 --- a/src/queue.h +++ b/src/queue.h @@ -28,7 +28,6 @@ #define queue_maxsuper 50 #define queue_sizeinit 100 #define queue_sizegrow 2 -#define queue_search_window 8 /* Counters. */ enum { @@ -55,7 +54,8 @@ struct queue { } __attribute__((aligned(64))); /* Function prototypes. */ -struct task *queue_gettask(struct queue *q, const struct task *prev, int blocking); +struct task *queue_gettask(struct queue *q, const struct task *prev, + int blocking, int queue_search_window); void queue_init(struct queue *q, struct task *tasks); void queue_insert(struct queue *q, struct task *t); diff --git a/src/runner.c b/src/runner.c index 93d2cd72aeb527b333c7bd3fe07fdd773258e4b1..f02a6c5e152f4305145911099ae1f454b6f5a9a1 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1198,7 +1198,7 @@ void *runner_main(void *data) { /* Get the task. */ TIMER_TIC - t = scheduler_gettask(sched, r->qid, prev); + t = scheduler_gettask(sched, r->qid, prev, e->queue_search_window); TIMER_TOC(timer_gettask); /* Did I get anything? */ diff --git a/src/scheduler.c b/src/scheduler.c index a83416aad4ed07ee55107775221e0c5b6b38b0f7..5d0367fdc2f28f5b941491bdfe7b91d5541457c6 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -1066,8 +1066,8 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) { break; case task_type_send: #ifdef WITH_MPI - if ((err = MPI_Isend(t->ci->parts, t->ci->count, s->part_mpi_type, - t->cj->nodeID, t->flags, MPI_COMM_WORLD, + if ((err = MPI_Isend(t->ci->parts, t->ci->count, s->part_mpi_type, + t->cj->nodeID, t->flags, MPI_COMM_WORLD, &t->req)) != MPI_SUCCESS) { char buff[MPI_MAX_ERROR_STRING]; int len; @@ -1186,12 +1186,14 @@ struct task *scheduler_unlock(struct scheduler *s, struct task *t) { * @param s The #scheduler. * @param qid The ID of the preferred #queue. * @param prev the previous task that was run. + * @param queue_search_window window to search for overlapping tasks. * * @return A pointer to a #task or @c NULL if there are no available tasks. */ struct task *scheduler_gettask(struct scheduler *s, int qid, - const struct task *prev) { + const struct task *prev, + int queue_search_window) { struct task *res = NULL; int k, nr_queues = s->nr_queues; @@ -1210,7 +1212,7 @@ struct task *scheduler_gettask(struct scheduler *s, int qid, /* Try to get a task from the suggested queue. */ if (s->queues[qid].count > 0) { TIMER_TIC - res = queue_gettask(&s->queues[qid], prev, 0); + res = queue_gettask(&s->queues[qid], prev, 0, queue_search_window); TIMER_TOC(timer_qget); if (res != NULL) break; } @@ -1223,7 +1225,8 @@ struct task *scheduler_gettask(struct scheduler *s, int qid, for (k = 0; k < scheduler_maxsteal && count > 0; k++) { int ind = rand_r(&seed) % count; TIMER_TIC - res = queue_gettask(&s->queues[qids[ind]], prev, 0); + res = queue_gettask(&s->queues[qids[ind]], prev, 0, + queue_search_window); TIMER_TOC(timer_qsteal); if (res != NULL) break; diff --git a/src/scheduler.h b/src/scheduler.h index 5ec6813fb02f4504a56f8ed8bf138615a73c1a6a..d7b00f485ea7ee2841ac440f30bf33b2ebf2861c 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -109,7 +109,8 @@ struct scheduler { void scheduler_init(struct scheduler *s, struct space *space, int nr_tasks, int nr_queues, unsigned int flags, int nodeID); struct task *scheduler_gettask(struct scheduler *s, int qid, - const struct task* prev); + const struct task* prev, + int queue_search_window); void scheduler_enqueue(struct scheduler *s, struct task *t); void scheduler_start(struct scheduler *s, unsigned int mask); void scheduler_reset(struct scheduler *s, int nr_tasks);