void pgstrom_perfmon_explain(pgstrom_perfmon *pfm, ExplainState *es) { double n = (double)pfm->num_samples; char buf[256]; if (!pfm->enabled) return; snprintf(buf, sizeof(buf), "%.3f ms", (double)pfm->time_to_load / 1000.0); ExplainPropertyText("Total time to load", buf, es); snprintf(buf, sizeof(buf), "%.3f ms", (double)pfm->time_in_sendq / n / 1000.0); ExplainPropertyText("Avg time in send-mq", buf, es); snprintf(buf, sizeof(buf), "%.3f ms", (double)pfm->time_kern_build / 1000.0); ExplainPropertyText("Max time to build kernel", buf, es); snprintf(buf, sizeof(buf), "%.3f ms", (double)pfm->time_dma_send / n / 1000.0); ExplainPropertyText("Avg time of DMA send", buf, es); snprintf(buf, sizeof(buf), "%.3f ms", (double)pfm->time_dma_send / 1000.0); ExplainPropertyText("Total time of DMA send", buf, es); snprintf(buf, sizeof(buf), "%.3f ms", (double)pfm->time_kern_exec / n / 1000.0); ExplainPropertyText("Avg time of kernel exec", buf, es); snprintf(buf, sizeof(buf), "%.3f ms", (double)pfm->time_kern_exec / 1000.0); ExplainPropertyText("Total time of kernel exec", buf, es); snprintf(buf, sizeof(buf), "%.3f ms", (double)pfm->time_dma_recv / n / 1000.0); ExplainPropertyText("Avg time of DMA recv", buf, es); snprintf(buf, sizeof(buf), "%.3f ms", (double)pfm->time_dma_recv / 1000.0); ExplainPropertyText("Total time of DMA recv", buf, es); snprintf(buf, sizeof(buf), "%.3f ms", (double)pfm->time_in_recvq / n / 1000.0); ExplainPropertyText("Avg time in recv-mq", buf, es); }
/* ------------------------------------------------------------ * * Routines copied from core PostgreSQL implementation * * ------------------------------------------------------------ */ void show_scan_qual(List *qual, const char *qlabel, PlanState *planstate, List *ancestors, ExplainState *es) { bool useprefix; Node *node; List *context; char *exprstr; useprefix = (IsA(planstate->plan, SubqueryScan) || es->verbose); /* No work if empty qual */ if (qual == NIL) return; /* Convert AND list to explicit AND */ node = (Node *) make_ands_explicit(qual); /* Set up deparsing context */ context = deparse_context_for_planstate((Node *) planstate, ancestors, es->rtable, es->rtable_names); /* Deparse the expression */ exprstr = deparse_expression(node, context, useprefix, false); /* And add to es->str */ ExplainPropertyText(qlabel, exprstr, es); }
void show_device_kernel(Datum dprog_key, ExplainState *es) { StringInfoData str; const char *kernel_source; int32 extra_flags; if (!es->verbose) return; kernel_source = pgstrom_get_devprog_kernel_source(dprog_key); extra_flags = pgstrom_get_devprog_extra_flags(dprog_key); initStringInfo(&str); /* * In case of EXPLAIN command context, we show the built-in logics * like a usual #include preprocessor command. * Practically, clCreateProgramWithSource() accepts multiple cstrings * as if external files are included. */ if (extra_flags & DEVKERNEL_NEEDS_DEBUG) appendStringInfo(&str, "#define PGSTROM_KERNEL_DEBUG 1\n"); appendStringInfo(&str, "#include \"opencl_common.h\"\n"); if (extra_flags & DEVFUNC_NEEDS_TIMELIB) appendStringInfo(&str, "#include \"opencl_timelib.h\"\n"); if (extra_flags & DEVFUNC_NEEDS_TEXTLIB) appendStringInfo(&str, "#include \"opencl_textlib.h\"\n"); if (extra_flags & DEVFUNC_NEEDS_NUMERICLIB) appendStringInfo(&str, "#include \"opencl_numericlib.h\"\n"); if (extra_flags & DEVKERNEL_NEEDS_GPUSCAN) appendStringInfo(&str, "#include \"opencl_gpuscan.h\"\n"); if (extra_flags & DEVKERNEL_NEEDS_GPUSORT) appendStringInfo(&str, "#include \"opencl_gpusort.h\"\n"); if (extra_flags & DEVKERNEL_NEEDS_HASHJOIN) appendStringInfo(&str, "#include \"opencl_hashjoin.h\"\n"); appendStringInfo(&str, "\n%s", kernel_source); ExplainPropertyText("Kernel Source", str.data, es); pfree(str.data); }
void pgstrom_perfmon_explain(pgstrom_perfmon *pfm, ExplainState *es) { bool multi_kernel = false; char buf[256]; if (!pfm->enabled || pfm->num_samples == 0) return; /* common performance statistics */ ExplainPropertyInteger("number of requests", pfm->num_samples, es); if (pfm->time_inner_load > 0) { snprintf(buf, sizeof(buf), "%s", usecond_unitary_format((double)pfm->time_inner_load)); ExplainPropertyText("total time for inner load", buf, es); snprintf(buf, sizeof(buf), "%s", usecond_unitary_format((double)pfm->time_outer_load)); ExplainPropertyText("total time for outer load", buf, es); } else { snprintf(buf, sizeof(buf), "%s", usecond_unitary_format((double)pfm->time_outer_load)); ExplainPropertyText("total time to load", buf, es); } if (pfm->time_materialize > 0) { snprintf(buf, sizeof(buf), "%s", usecond_unitary_format((double)pfm->time_materialize)); ExplainPropertyText("total time to materialize", buf, es); } if (pfm->num_samples > 0 && (pfm->time_in_sendq > 0 || pfm->time_in_recvq > 0)) { snprintf(buf, sizeof(buf), "%s", usecond_unitary_format((double)pfm->time_in_sendq / (double)pfm->num_samples)); ExplainPropertyText("average time in send-mq", buf, es); snprintf(buf, sizeof(buf), "%s", usecond_unitary_format((double)pfm->time_in_recvq / (double)pfm->num_samples)); ExplainPropertyText("average time in recv-mq", buf, es); } if (pfm->time_kern_build > 0) { snprintf(buf, sizeof(buf), "%s", usecond_unitary_format((double)pfm->time_kern_build)); ExplainPropertyText("max time to build kernel", buf, es); } if (pfm->num_dma_send > 0) { double band = (((double)pfm->bytes_dma_send * 1000000.0) / (double)pfm->time_dma_send); snprintf(buf, sizeof(buf), "%s/sec, len: %s, time: %s, count: %u", bytesz_unitary_format(band), bytesz_unitary_format((double)pfm->bytes_dma_send), usecond_unitary_format((double)pfm->time_dma_send), pfm->num_dma_send); ExplainPropertyText("DMA send", buf, es); } if (pfm->num_dma_recv > 0) { double band = (((double)pfm->bytes_dma_recv * 1000000.0) / (double)pfm->time_dma_recv); snprintf(buf, sizeof(buf), "%s/sec, len: %s, time: %s, count: %u", bytesz_unitary_format(band), bytesz_unitary_format((double)pfm->bytes_dma_recv), usecond_unitary_format((double)pfm->time_dma_recv), pfm->num_dma_recv); ExplainPropertyText("DMA recv", buf, es); } /* only gpupreagg */ if (pfm->num_kern_prep > 0) { multi_kernel = true; snprintf(buf, sizeof(buf), "total: %s, avg: %s, count: %u", usecond_unitary_format((double)pfm->time_kern_prep), usecond_unitary_format((double)pfm->time_kern_prep / (double)pfm->num_kern_prep), pfm->num_kern_prep); ExplainPropertyText("prep kernel exec", buf, es); } /* only gpupreagg */ if (pfm->num_kern_sort > 0) { multi_kernel = true; snprintf(buf, sizeof(buf), "total: %s, avg: %s, count: %u", usecond_unitary_format((double)pfm->time_kern_sort), usecond_unitary_format((double)pfm->time_kern_sort / (double)pfm->num_kern_sort), pfm->num_kern_sort); ExplainPropertyText("sort kernel exec", buf, es); } /* only gpuhashjoin */ if (pfm->num_kern_proj > 0) { multi_kernel = true; snprintf(buf, sizeof(buf), "total: %s, avg: %s, count: %u", usecond_unitary_format((double)pfm->time_kern_proj), usecond_unitary_format((double)pfm->time_kern_proj / (double)pfm->num_kern_proj), pfm->num_kern_exec); ExplainPropertyText("proj kernel exec", buf, es); } if (pfm->num_kern_exec > 0) { const char *label = (multi_kernel ? "main kernel exec" : "kernel exec"); snprintf(buf, sizeof(buf), "total: %s, avg: %s, count: %u", usecond_unitary_format((double)pfm->time_kern_exec), usecond_unitary_format((double)pfm->time_kern_exec / (double)pfm->num_kern_exec), pfm->num_kern_exec); ExplainPropertyText(label, buf, es); } /* for debugging if any */ if (pfm->time_debug1 > 0) { snprintf(buf, sizeof(buf), "debug1: %s", usecond_unitary_format((double)pfm->time_debug1)); ExplainPropertyText("debug-1", buf, es); } if (pfm->time_debug2 > 0) { snprintf(buf, sizeof(buf), "debug2: %s", usecond_unitary_format((double)pfm->time_debug2)); ExplainPropertyText("debug-2", buf, es); } if (pfm->time_debug3 > 0) { snprintf(buf, sizeof(buf), "debug3: %s", usecond_unitary_format((double)pfm->time_debug3)); ExplainPropertyText("debug-3", buf, es); } if (pfm->time_debug4 > 0) { snprintf(buf, sizeof(buf), "debug4: %s", usecond_unitary_format((double)pfm->time_debug4)); ExplainPropertyText("debug-4", buf, es); } }
/* * twitterExplain * Produce extra output for EXPLAIN */ static void twitterExplain(ForeignScanState *node, ExplainState *es) { ExplainPropertyText("Twitter API", "Search", es); }