From 5b94910fc4c6a47856290e9c23f9a905cf63c1eb Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 17 Apr 2019 14:38:23 +0200 Subject: Add and use a new timer API. --- mg2d.c | 144 +++++++++++++++++++++++++++++++---------------------------------- 1 file changed, 68 insertions(+), 76 deletions(-) (limited to 'mg2d.c') diff --git a/mg2d.c b/mg2d.c index a22a0a5..6639879 100644 --- a/mg2d.c +++ b/mg2d.c @@ -34,6 +34,7 @@ #include "mg2d_boundary_internal.h" #include "mg2d_constants.h" #include "ndarray.h" +#include "timer.h" #include "transfer.h" typedef struct MG2DLevel { @@ -52,11 +53,11 @@ typedef struct MG2DLevel { /* timings */ int64_t count_cycles; - int64_t time_solve; - int64_t time_prolong; - int64_t time_restrict; - int64_t time_correct; - int64_t time_reinit; + Timer timer_solve; + Timer timer_prolong; + Timer timer_restrict; + Timer timer_correct; + Timer timer_reinit; } MG2DLevel; struct MG2DInternal { @@ -74,10 +75,8 @@ struct MG2DInternal { int cpuflags; - int64_t time_solve; - int64_t count_solve; - int64_t time_levels_init; - int64_t count_levels_init; + Timer timer_solve; + Timer timer_levels_init; }; static void log_callback(MG2DLogger *log, int level, const char *fmt, va_list vl) @@ -113,16 +112,13 @@ static int coarse_correct_task(void *arg, unsigned int job_idx, unsigned int thr static int mg_relax_step(MG2DContext *ctx, MG2DLevel *level, const char *step_desc) { double res_old; - int64_t start; int ret; res_old = level->solver->residual_max; - start = gettime(); - + mg2di_timer_start(&level->timer_solve); ret = mg2di_egs_solve(level->solver); - - level->time_solve += gettime() - start; + mg2di_timer_stop(&level->timer_solve); if (ret < 0) return ret; @@ -140,7 +136,7 @@ static int mg_solve_subgrid(MG2DContext *ctx, MG2DLevel *level) /* on the refined levels, use zero as the initial guess for the * solution (correction for the upper level) */ if (level->depth > 0) { - int64_t start = gettime(); + mg2di_timer_start(&level->timer_reinit); memset(level->solver->u->data, 0, sizeof(*level->solver->u->data) * level->solver->u->stride[0] * level->solver->domain_size[1]); @@ -149,9 +145,8 @@ static int mg_solve_subgrid(MG2DContext *ctx, MG2DLevel *level) ret = mg2di_egs_init(level->solver, level->egs_init_flags); if (ret < 0) return ret; + mg2di_timer_stop(&level->timer_reinit); level->egs_init_flags |= EGS_INIT_FLAG_SAME_DIFF_COEFFS; - - level->time_reinit += gettime() - start; } res_old = level->solver->residual_max; @@ -168,7 +163,6 @@ static int mg_solve_subgrid(MG2DContext *ctx, MG2DLevel *level) for (int i = 0; i < ctx->nb_cycles; i++) { double res_prev; - int64_t start; /* pre-restrict relaxation */ for (int j = 0; j < ctx->nb_relax_pre; j++) { @@ -178,12 +172,12 @@ static int mg_solve_subgrid(MG2DContext *ctx, MG2DLevel *level) } /* restrict the residual as to the coarser-level rhs */ - start = gettime(); + mg2di_timer_start(&level->timer_restrict); ret = mg2di_gt_transfer(level->transfer_restrict, level->child->solver->rhs, level->solver->residual); + mg2di_timer_stop(&level->timer_restrict); if (ret < 0) return ret; - level->time_restrict += gettime() - start; /* solve on the coarser level */ ret = mg_solve_subgrid(ctx, level->child); @@ -191,27 +185,25 @@ static int mg_solve_subgrid(MG2DContext *ctx, MG2DLevel *level) return ret; /* prolongate the coarser-level correction */ - start = gettime(); + mg2di_timer_start(&level->timer_prolong); ret = mg2di_gt_transfer(level->transfer_prolong, level->prolong_tmp, level->child->solver->u); + mg2di_timer_stop(&level->timer_prolong); if (ret < 0) return ret; - level->time_prolong += gettime() - start; /* apply the correction */ - start = gettime(); - + mg2di_timer_start(&level->timer_correct); tp_execute(ctx->priv->tp, level->solver->domain_size[1], coarse_correct_task, level); - - level->time_correct += gettime() - start; + mg2di_timer_stop(&level->timer_correct); /* re-init the current-level solver (re-calc the residual) */ res_prev = level->solver->residual_max; - start = gettime(); + mg2di_timer_start(&level->timer_reinit); ret = mg2di_egs_init(level->solver, 0); + mg2di_timer_stop(&level->timer_reinit); if (ret < 0) return ret; - level->time_reinit += gettime() - start; log_relax_step(ctx, level, "correct", res_prev, level->solver->residual_max); @@ -488,7 +480,6 @@ int mg2d_solve(MG2DContext *ctx) MG2DInternal *priv = ctx->priv; MG2DLevel *root; EGSContext *s_root; - int64_t time_start, start; double res_orig, res_prev, res_cur; int ret; @@ -507,24 +498,19 @@ int mg2d_solve(MG2DContext *ctx) root = priv->root; s_root = root->solver; - time_start = gettime(); - - start = gettime(); + mg2di_timer_start(&priv->timer_solve); + mg2di_timer_start(&priv->timer_levels_init); ret = mg_levels_init(ctx); + mg2di_timer_stop(&priv->timer_levels_init); if (ret < 0) - return ret; - - priv->time_levels_init += gettime() - start; - priv->count_levels_init++; - - start = gettime(); + goto finish; + mg2di_timer_start(&root->timer_reinit); ret = mg2di_egs_init(s_root, 0); + mg2di_timer_stop(&root->timer_reinit); if (ret < 0) - return ret; - - root->time_reinit += gettime() - start; + goto finish; res_orig = s_root->residual_max; res_prev = res_orig; @@ -542,10 +528,7 @@ int mg2d_solve(MG2DContext *ctx) //mg2di_ndarray_copy(priv->u, s_root->u); - priv->time_solve += gettime() - time_start; - priv->count_solve++; - - return 0; + goto finish; } mg2di_log(&priv->logger, MG2D_LOG_VERBOSE, @@ -564,6 +547,8 @@ int mg2d_solve(MG2DContext *ctx) "Maximum number of iterations (%d) reached\n", ctx->maxiter); fail: mg2di_log(&priv->logger, MG2D_LOG_ERROR, "The solver failed to converge\n"); +finish: + mg2di_timer_stop(&priv->timer_solve); return ret; } @@ -607,6 +592,12 @@ static MG2DLevel *mg_level_alloc(enum EGSType type, const size_t domain_size) if (!level->solver) goto fail; + mg2di_timer_init(&level->timer_solve); + mg2di_timer_init(&level->timer_prolong); + mg2di_timer_init(&level->timer_restrict); + mg2di_timer_init(&level->timer_correct); + mg2di_timer_init(&level->timer_reinit); + return level; fail: mg_level_free(&level); @@ -738,6 +729,9 @@ MG2DContext *mg2d_solver_alloc(size_t domain_size) ctx->log_level = MG2D_LOG_INFO; ctx->nb_threads = 1; + mg2di_timer_init(&priv->timer_levels_init); + mg2di_timer_init(&priv->timer_solve); + return ctx; fail: mg2d_solver_free(&ctx); @@ -788,8 +782,8 @@ void mg2d_print_stats(MG2DContext *ctx, const char *prefix) prefix = ""; mg2di_log(&priv->logger, MG2D_LOG_VERBOSE, "%s%ld solves; %g s total time; %g ms avg per call; %g avg cycles per solve\n", - prefix, priv->count_solve, priv->time_solve / 1e6, priv->time_solve / 1e3 / priv->count_solve, - (double)level->count_cycles / priv->count_solve); + prefix, priv->timer_solve.nb_runs, priv->timer_solve.time_nsec / 1e9, priv->timer_solve.time_nsec / 1e6 / priv->timer_solve.nb_runs, + (double)level->count_cycles / priv->timer_solve.nb_runs); while (level) { char buf[1024], *p; @@ -798,70 +792,68 @@ void mg2d_print_stats(MG2DContext *ctx, const char *prefix) EGSRelaxContext *r = NULL; EGSExactContext *e = NULL; - int64_t level_total = level->time_solve + level->time_prolong + level->time_restrict + - level->time_correct + level->time_reinit; + int64_t level_total = level->timer_solve.time_nsec + level->timer_prolong.time_nsec + level->timer_restrict.time_nsec + + level->timer_correct.time_nsec + level->timer_reinit.time_nsec; if (level->solver->solver_type == EGS_SOLVER_RELAXATION) r = level->solver->solver_data; else if (level->solver->solver_type == EGS_SOLVER_EXACT) e = level->solver->solver_data; - level_total = level->time_solve + level->time_prolong + level->time_restrict + - level->time_correct + level->time_reinit; - levels_total += level_total; p = buf; ret = snprintf(p, sizeof(buf) - (p - buf), "%2.2f%% level %d: %ld cycles %g s total time %g ms avg per call", - level_total * 100.0 / priv->time_solve, level->depth, level->count_cycles, - level_total / 1e6, level_total / 1e3 / level->count_cycles); + level_total * 100.0 / priv->timer_solve.time_nsec, level->depth, level->count_cycles, + level_total / 1e9, level_total / 1e6 / level->count_cycles); if (ret > 0) p += ret; ret = snprintf(p, sizeof(buf) - (p - buf), "||%2.2f%% solve %2.2f%% reinit ", - level->time_solve * 100.0 / level_total, - level->time_reinit * 100.0 / level_total); + level->timer_solve.time_nsec * 100.0 / level_total, + level->timer_reinit.time_nsec * 100.0 / level_total); if (ret > 0) p += ret; if (level->child) { ret = snprintf(p, sizeof(buf) - (p - buf), "%2.2f%% prolong %2.2f%% restrict %2.2f%% correct", - level->time_prolong * 100.0 / level_total, - level->time_restrict * 100.0 / level_total, - level->time_correct * 100.0 / level_total); + level->timer_prolong.time_nsec * 100.0 / level_total, + level->timer_restrict.time_nsec * 100.0 / level_total, + level->timer_correct.time_nsec * 100.0 / level_total); if (ret > 0) p += ret; } ret = snprintf(p, sizeof(buf) - (p - buf), "||%2.2f%% init %2.2f%% residual %2.2f%% boundaries (%2.2f%% fixval %2.2f%% reflect %2.2f%% falloff %2.2f%% corners)", - level->solver->time_init * 100.0 / level->solver->time_total, - level->solver->time_res_calc * 100.0 / level->solver->time_total, - level->solver->time_boundaries * 100.0 / level->solver->time_total, - level->solver->time_bnd_fixval * 100.0 / level->solver->time_total, - level->solver->time_bnd_reflect * 100.0 / level->solver->time_total, - level->solver->time_bnd_falloff * 100.0 / level->solver->time_total, - level->solver->time_bnd_corners * 100.0 / level->solver->time_total); + level->solver->timer_init.time_nsec * 100.0 / level->solver->timer_solve.time_nsec, + level->solver->timer_res_calc.time_nsec * 100.0 / level->solver->timer_solve.time_nsec, + level->solver->timer_bnd.time_nsec * 100.0 / level->solver->timer_solve.time_nsec, + level->solver->timer_bnd_fixval.time_nsec * 100.0 / level->solver->timer_solve.time_nsec, + level->solver->timer_bnd_reflect.time_nsec * 100.0 / level->solver->timer_solve.time_nsec, + level->solver->timer_bnd_falloff.time_nsec * 100.0 / level->solver->timer_solve.time_nsec, + level->solver->timer_bnd_corners.time_nsec * 100.0 / level->solver->timer_solve.time_nsec); if (ret > 0) p += ret; if (r) { ret = snprintf(p, sizeof(buf) - (p - buf), " %2.2f%% correct", - r->time_correct * 100.0 / level->solver->time_total); + r->timer_correct.time_nsec * 100.0 / level->solver->timer_solve.time_nsec); if (ret > 0) p += ret; } else if (e) { ret = snprintf(p, sizeof(buf) - (p - buf), " %2.2f%% const %2.2f%% bicgstab (%ld; %g it/slv) %2.2f%% lu (%ld) %2.2f%% export", - e->time_mat_construct * 100.0 / level->solver->time_total, - e->time_bicgstab_solve * 100.0 / level->solver->time_total, e->count_bicgstab_solve, (double)e->bicgstab_iterations / e->count_bicgstab_solve, - e->time_lu_solve * 100.0 / level->solver->time_total, e->count_lu_solve, - e->time_export * 100.0 / level->solver->time_total); + e->timer_mat_construct.time_nsec * 100.0 / level->solver->timer_solve.time_nsec, + e->timer_bicgstab.time_nsec * 100.0 / level->solver->timer_solve.time_nsec, + e->timer_bicgstab.nb_runs, (double)e->bicgstab_iterations / e->timer_bicgstab.nb_runs, + e->timer_lu_solve.time_nsec * 100.0 / level->solver->timer_solve.time_nsec, e->timer_lu_solve.nb_runs, + e->timer_export.time_nsec * 100.0 / level->solver->timer_solve.time_nsec); if (ret > 0) p += ret; } @@ -872,14 +864,14 @@ void mg2d_print_stats(MG2DContext *ctx, const char *prefix) mg2di_log(&priv->logger, MG2D_LOG_VERBOSE, "%s%2.2f%% levels init %g s total time %g ms avg per call\n", - prefix, priv->time_levels_init * 100.0 / priv->time_solve, - priv->time_levels_init / 1e6, priv->time_levels_init / 1e3 / priv->count_levels_init); + prefix, priv->timer_levels_init.time_nsec * 100.0 / priv->timer_solve.time_nsec, + priv->timer_levels_init.time_nsec / 1e9, priv->timer_levels_init.time_nsec / 1e6 / priv->timer_levels_init.nb_runs); - other = priv->time_solve - levels_total - priv->time_levels_init; + other = priv->timer_solve.time_nsec - levels_total - priv->timer_levels_init.time_nsec; mg2di_log(&priv->logger, MG2D_LOG_VERBOSE, "%s%2.2f%% other %g s total time %g ms avg per call\n", - prefix, other * 100.0 / priv->time_solve, - other / 1e6, other / 1e3 / priv->count_solve); + prefix, other * 100.0 / priv->timer_solve.time_nsec, + other / 1e9, other / 1e6 / priv->timer_solve.nb_runs); } -- cgit v1.2.3