Commit 0e7632c6 authored by Pedro Gonnet's avatar Pedro Gonnet
Browse files

make engine_marktasks use the threadpool, needs two passes since it can't...

make engine_marktasks use the threadpool, needs two passes since it can't process the tasks in topological order.
parent 18225b08
......@@ -23,6 +23,7 @@
#include "inline.h"
#define atomic_add(v, i) __sync_fetch_and_add(v, i)
#define atomic_or(v, i) __sync_fetch_and_or(v, i)
#define atomic_inc(v) atomic_add(v, 1)
#define atomic_dec(v) atomic_add(v, -1)
#define atomic_cas(v, o, n) __sync_val_compare_and_swap(v, o, n)
......
......@@ -1507,129 +1507,137 @@ void engine_maketasks(struct engine *e) {
* @return 1 if the space has to be rebuilt, 0 otherwise.
*/
int engine_marktasks(struct engine *e) {
struct scheduler *s = &e->sched;
const int ti_end = e->ti_current;
const int nr_tasks = s->nr_tasks;
const int *const ind = s->tasks_ind;
struct task *tasks = s->tasks;
const ticks tic = getticks();
void engine_marktasks_fixdt_mapper(void *map_data, void *extra_data) {
/* Unpack the arguments. */
struct task *t = (struct task *)map_data;
int *rebuild_space = (int *)extra_data;
/* Much less to do here if we're on a fixed time-step. */
if (e->policy & engine_policy_fixdt) {
/* Pair? */
if (t->type == task_type_pair ||
(t->type == task_type_sub && t->cj != NULL)) {
/* Run through the tasks and mark as skip or not. */
for (int k = 0; k < nr_tasks; k++) {
/* Local pointers. */
const struct cell *ci = t->ci;
const struct cell *cj = t->cj;
/* Get a handle on the kth task. */
struct task *t = &tasks[ind[k]];
/* Too much particle movement? */
if (t->tight &&
(fmaxf(ci->h_max, cj->h_max) + ci->dx_max + cj->dx_max > cj->dmin ||
ci->dx_max > space_maxreldx * ci->h_max ||
cj->dx_max > space_maxreldx * cj->h_max))
*rebuild_space = 1;
/* Pair? */
if (t->type == task_type_pair ||
(t->type == task_type_sub && t->cj != NULL)) {
}
/* Local pointers. */
const struct cell *ci = t->ci;
const struct cell *cj = t->cj;
/* Sort? */
else if (t->type == task_type_sort) {
/* Too much particle movement? */
if (t->tight &&
(fmaxf(ci->h_max, cj->h_max) + ci->dx_max + cj->dx_max > cj->dmin ||
ci->dx_max > space_maxreldx * ci->h_max ||
cj->dx_max > space_maxreldx * cj->h_max))
return 1;
/* If all the sorts have been done, make this task implicit. */
if (!(t->flags & (t->flags ^ t->ci->sorted))) t->implicit = 1;
}
}
}
void engine_marktasks_sorts_mapper(void *map_data, void *extra_data) {
/* Unpack the arguments. */
struct task *t = (struct task *)map_data;
if (t->type == task_type_sort) {
t->flags = 0;
t->skip = 1;
}
}
/* Sort? */
else if (t->type == task_type_sort) {
void engine_marktasks_mapper(void *map_data, void *extra_data) {
/* Unpack the arguments. */
struct task *t = (struct task *)map_data;
const int ti_end = ((int *)extra_data)[0];
int *rebuild_space = &((int *)extra_data)[1];
/* If all the sorts have been done, make this task implicit. */
if (!(t->flags & (t->flags ^ t->ci->sorted))) t->implicit = 1;
}
}
/* Single-cell task? */
if (t->type == task_type_self || t->type == task_type_ghost ||
(t->type == task_type_sub && t->cj == NULL)) {
/* Multiple-timestep case */
} else {
/* Set this task's skip. */
t->skip = (t->ci->ti_end_min > ti_end);
}
/* Run through the tasks and mark as skip or not. */
for (int k = 0; k < nr_tasks; k++) {
/* Pair? */
else if (t->type == task_type_pair ||
(t->type == task_type_sub && t->cj != NULL)) {
/* Get a handle on the kth task. */
struct task *t = &tasks[ind[k]];
/* Local pointers. */
const struct cell *ci = t->ci;
const struct cell *cj = t->cj;
/* Sort-task? Note that due to the task ranking, the sorts
will all come before the pairs. */
if (t->type == task_type_sort) {
/* Set this task's skip. */
t->skip = (ci->ti_end_min > ti_end && cj->ti_end_min > ti_end);
/* Re-set the flags. */
t->flags = 0;
t->skip = 1;
/* Too much particle movement? */
if (t->tight &&
(fmaxf(ci->h_max, cj->h_max) + ci->dx_max + cj->dx_max > cj->dmin ||
ci->dx_max > space_maxreldx * ci->h_max ||
cj->dx_max > space_maxreldx * cj->h_max))
*rebuild_space = 1;
/* Set the sort flags. */
if (!t->skip && t->type == task_type_pair) {
if (!(ci->sorted & (1 << t->flags))) {
atomic_or(&ci->sorts->flags, (1 << t->flags));
ci->sorts->skip = 0;
}
if (!(cj->sorted & (1 << t->flags))) {
atomic_or(&cj->sorts->flags, (1 << t->flags));
cj->sorts->skip = 0;
}
}
/* Single-cell task? */
else if (t->type == task_type_self || t->type == task_type_ghost ||
(t->type == task_type_sub && t->cj == NULL)) {
}
/* Set this task's skip. */
t->skip = (t->ci->ti_end_min > ti_end);
}
/* Kick? */
else if (t->type == task_type_kick) {
t->skip = (t->ci->ti_end_min > ti_end);
t->ci->updated = 0;
t->ci->g_updated = 0;
}
/* Pair? */
else if (t->type == task_type_pair ||
(t->type == task_type_sub && t->cj != NULL)) {
/* Local pointers. */
const struct cell *ci = t->ci;
const struct cell *cj = t->cj;
/* Set this task's skip. */
t->skip = (ci->ti_end_min > ti_end && cj->ti_end_min > ti_end);
/* Too much particle movement? */
if (t->tight &&
(fmaxf(ci->h_max, cj->h_max) + ci->dx_max + cj->dx_max > cj->dmin ||
ci->dx_max > space_maxreldx * ci->h_max ||
cj->dx_max > space_maxreldx * cj->h_max))
return 1;
/* Set the sort flags. */
if (!t->skip && t->type == task_type_pair) {
if (!(ci->sorted & (1 << t->flags))) {
ci->sorts->flags |= (1 << t->flags);
ci->sorts->skip = 0;
}
if (!(cj->sorted & (1 << t->flags))) {
cj->sorts->flags |= (1 << t->flags);
cj->sorts->skip = 0;
}
}
/* Drift? */
else if (t->type == task_type_drift)
t->skip = 0;
}
/* Init? */
else if (t->type == task_type_init) {
/* Set this task's skip. */
t->skip = (t->ci->ti_end_min > ti_end);
}
/* Kick? */
else if (t->type == task_type_kick) {
t->skip = (t->ci->ti_end_min > ti_end);
t->ci->updated = 0;
t->ci->g_updated = 0;
}
/* None? */
else if (t->type == task_type_none)
t->skip = 1;
}
/* Drift? */
else if (t->type == task_type_drift)
t->skip = 0;
int engine_marktasks(struct engine *e) {
/* Init? */
else if (t->type == task_type_init) {
/* Set this task's skip. */
t->skip = (t->ci->ti_end_min > ti_end);
}
struct scheduler *s = &e->sched;
const ticks tic = getticks();
/* None? */
else if (t->type == task_type_none)
t->skip = 1;
}
/* Much less to do here if we're on a fixed time-step. */
if (e->policy & engine_policy_fixdt) {
/* Run through the tasks and mark as skip or not. */
int rebuild_space = 0;
threadpool_map(&e->threadpool, engine_marktasks_fixdt_mapper, s->tasks,
s->nr_tasks, sizeof(struct task), &rebuild_space);
return rebuild_space;
/* Multiple-timestep case */
} else {
/* Run through the tasks and mark as skip or not. */
int extra_data[2] = {e->ti_current, 0};
threadpool_map(&e->threadpool, engine_marktasks_sorts_mapper, s->tasks,
s->nr_tasks, sizeof(struct task), NULL);
threadpool_map(&e->threadpool, engine_marktasks_mapper, s->tasks,
s->nr_tasks, sizeof(struct task), extra_data);
return extra_data[1];
}
if (e->verbose)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment