LCOV - code coverage report
Current view: top level - monetdb5/modules/mal - profiler.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 49 98 50.0 %
Date: 2024-04-25 20:03:45 Functions: 9 19 47.4 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : /*
      14             :  * Martin Kersten
      15             :  * Performance profiler
      16             :  * A key issue in developing fast programs using the Monet database
      17             :  * back-end requires a keen eye on where performance is lost.
      18             :  * Although performance tracking and measurements are highly
      19             :  * application dependent, a simple to use tool makes life
      20             :  * a lot easier.
      21             :  *
      22             :  * Activation of the performance monitor has a global effect,
      23             :  * i.e. all concurrent actions on the kernel are traced,
      24             :  * but the events are only sent to the client initiated
      25             :  * the profiler thread.
      26             :  *
      27             :  * The profiler event can be handled in several ways.
      28             :  * The default strategy is to ship the event record immediately over a stream
      29             :  * to a performance monitor.
      30             :  * An alternative strategy is preparation of off-line performance analysis.
      31             :  *
      32             :  * To reduce the  interference of performance measurement with
      33             :  * the experiments, the user can use an event cache, which is
      34             :  * emptied explicitly upon need.
      35             :  */
      36             : /*
      37             :  * Using the Monet Performance Profiler is constrained by the mal_profiler.
      38             :  */
      39             : #include "monetdb_config.h"
      40             : #include "gdk.h"
      41             : #include <time.h>
      42             : #include "mal_stack.h"
      43             : #include "mal_resolve.h"
      44             : #include "mal_exception.h"
      45             : #include "mal_client.h"
      46             : #include "mal_profiler.h"
      47             : #include "mal_interpreter.h"
      48             : #include "mal_runtime.h"
      49             : 
      50             : static str
      51           0 : CMDopenProfilerStream(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pc)
      52             : {
      53           0 :         (void) cntxt;
      54           0 :         (void) mb;
      55           0 :         (void) stk;
      56           0 :         (void) pc;
      57           0 :         int m = 0;
      58           0 :         if (pc->argc == 2 && getArgType(mb, pc, 1) == TYPE_int)
      59           0 :                 m = *getArgReference_int(stk, pc, 1);
      60           0 :         else if (pc->argc > 2)
      61           0 :                 m = -1;
      62           0 :         return openProfilerStream(cntxt, m);
      63             : }
      64             : 
      65             : static str
      66           0 : CMDcloseProfilerStream(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pc)
      67             : {
      68           0 :         (void) mb;
      69           0 :         (void) stk;
      70           0 :         (void) pc;
      71           0 :         return closeProfilerStream(cntxt);
      72             : }
      73             : 
      74             : // initialize SQL tracing
      75             : static str
      76           1 : CMDstartProfiler(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pc)
      77             : {
      78           1 :         (void) mb;
      79           1 :         (void) stk;
      80           1 :         (void) pc;
      81           1 :         (void) cntxt;
      82           1 :         return startProfiler(cntxt);
      83             : }
      84             : 
      85             : static str
      86           1 : CMDstopProfiler(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      87             : {
      88           1 :         (void) mb;
      89           1 :         (void) stk;
      90           1 :         (void) pci;
      91             : 
      92           1 :         return stopProfiler(cntxt);
      93             : }
      94             : 
      95             : // called by the SQL front end optional a directory to keep the traces.
      96             : static str
      97          18 : CMDstartTrace(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      98             : {
      99          18 :         (void) mb;
     100          18 :         (void) stk;
     101          18 :         (void) pci;
     102          18 :         renameVariables(mb);            // to keep in sync with explain
     103          18 :         return startTrace(cntxt);
     104             : }
     105             : 
     106             : static str
     107          22 : CMDstopTrace(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     108             : {
     109          22 :         (void) mb;
     110          22 :         (void) stk;
     111          22 :         (void) pci;
     112          22 :         return stopTrace(cntxt);
     113             : }
     114             : 
     115             : static str
     116           0 : CMDnoopProfiler(void *res)
     117             : {
     118           0 :         (void) res;                                     /* fool compiler */
     119           0 :         return MAL_SUCCEED;
     120             : }
     121             : 
     122             : static str
     123           0 : CMDcleanupTraces(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     124             : {
     125           0 :         (void) mb;
     126           0 :         (void) stk;
     127           0 :         (void) pci;
     128           0 :         cleanupTraces(cntxt);
     129           0 :         return MAL_SUCCEED;
     130             : }
     131             : 
     132             : static str
     133           8 : CMDgetTrace(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     134             : {
     135           8 :         str path = *getArgReference_str(stk, pci, 1);
     136           8 :         bat *res = getArgReference_bat(stk, pci, 0);
     137           8 :         BAT *bn;
     138             : 
     139           8 :         (void) cntxt;                           /* fool compiler */
     140           8 :         (void) mb;
     141           8 :         bn = getTrace(cntxt, path);
     142           8 :         if (bn) {
     143           8 :                 *res = bn->batCacheid;
     144           8 :                 BBPkeepref(bn);
     145           8 :                 return MAL_SUCCEED;
     146             :         }
     147           0 :         throw(MAL, "getTrace", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING "%s", path);
     148             : }
     149             : 
     150             : static str
     151           2 : CMDgetprofilerlimit(int *res)
     152             : {
     153           2 :         *res = getprofilerlimit();
     154           2 :         return MAL_SUCCEED;
     155             : }
     156             : 
     157             : static str
     158           0 : CMDsetprofilerlimit(void *res, int *lim)
     159             : {
     160           0 :         (void) res;
     161           0 :         setprofilerlimit(*lim);
     162           0 :         return MAL_SUCCEED;
     163             : }
     164             : 
     165             : /*
     166             :  * Tracing an active system.
     167             :  */
     168             : 
     169             : static str
     170           0 : CMDsetHeartbeat(void *res, int *ev)
     171             : {
     172           0 :         (void) res;
     173           0 :         setHeartbeat(*ev);
     174           0 :         return MAL_SUCCEED;
     175             : }
     176             : 
     177             : static str
     178           0 : CMDgetDiskReads(lng *ret)
     179             : {
     180           0 :         *ret = getDiskReads();
     181           0 :         return MAL_SUCCEED;
     182             : }
     183             : 
     184             : static str
     185           0 : CMDgetDiskWrites(lng *ret)
     186             : {
     187           0 :         *ret = getDiskWrites();
     188           0 :         return MAL_SUCCEED;
     189             : }
     190             : 
     191             : static str
     192           0 : CMDgetUserTime(lng *ret)
     193             : {
     194           0 :         *ret = getUserTime();
     195           0 :         return MAL_SUCCEED;
     196             : }
     197             : 
     198             : static str
     199           0 : CMDgetSystemTime(lng *ret)
     200             : {
     201           0 :         *ret = getUserTime();
     202           0 :         return MAL_SUCCEED;
     203             : }
     204             : 
     205             : static str
     206           5 : CMDcpustats(lng *user, lng *nice, lng *sys, lng *idle, lng *iowait)
     207             : {
     208           5 :         profilerGetCPUStat(user, nice, sys, idle, iowait);
     209           5 :         return MAL_SUCCEED;
     210             : }
     211             : 
     212             : static str
     213           5 : CMDcpuloadPercentage(int *cycles, int *io, lng *user, lng *nice, lng *sys,
     214             :                                          lng *idle, lng *iowait)
     215             : {
     216           5 :         lng userN, niceN, sysN, idleN, iowaitN, N;
     217           5 :         *cycles = 0;
     218           5 :         *io = 0;
     219           5 :         profilerGetCPUStat(&userN, &niceN, &sysN, &idleN, &iowaitN);
     220           5 :         N = (userN - *user + niceN - *nice + sysN - *sys);
     221           5 :         if (N) {
     222           0 :                 *cycles = (int) (((double) N) / (N + idleN - *idle + iowaitN - *iowait) * 100);
     223           0 :                 *io = (int) (((double) iowaitN - *iowait) / (N + idleN - *idle +
     224           0 :                                                                                                          iowaitN - *iowait) * 100);
     225             :         }
     226           5 :         return MAL_SUCCEED;
     227             : }
     228             : 
     229             : #include "mel.h"
     230             : mel_func profiler_init_funcs[] = {
     231             :  pattern("profiler", "start", CMDstartProfiler, true, "Start offline performance profiling", noargs),
     232             :  pattern("profiler", "stop", CMDstopProfiler, true, "Stop offline performance profiling", args(1,1, arg("",void))),
     233             :  pattern("profiler", "starttrace", CMDstartTrace, true, "Start collecting trace information", noargs),
     234             :  pattern("profiler", "stoptrace", CMDstopTrace, true, "Stop collecting trace information", args(1,1, arg("",void))),
     235             :  command("profiler", "setheartbeat", CMDsetHeartbeat, true, "Set heart beat performance tracing", args(1,2, arg("",void),arg("b",int))),
     236             :  command("profiler", "getlimit", CMDgetprofilerlimit, false, "Get profiler limit", args(1,1, arg("",int))),
     237             :  command("profiler", "setlimit", CMDsetprofilerlimit, true, "Set profiler limit", args(1,2, arg("",void),arg("l",int))),
     238             :  pattern("profiler", "openstream", CMDopenProfilerStream, false, "Start profiling the events, send to output stream", args(1,1, arg("",void))),
     239             :  pattern("profiler", "openstream", CMDopenProfilerStream, false, "Start profiling the events, send to output stream", args(1,2, arg("",void), arg("m",int))),
     240             :  pattern("profiler", "closestream", CMDcloseProfilerStream, false, "Stop offline proviling", args(1,1, arg("",void))),
     241             :  command("profiler", "noop", CMDnoopProfiler, false, "Fetch any pending performance events", args(1,1, arg("",void))),
     242             :  pattern("profiler", "getTrace", CMDgetTrace, false, "Get the trace details of a specific event", args(1,2, batargany("",1),arg("e",str))),
     243             :  pattern("profiler", "cleanup", CMDcleanupTraces, true, "Remove the temporary tables for profiling", args(1,1, arg("",void))),
     244             :  command("profiler", "getDiskReads", CMDgetDiskReads, false, "Obtain the number of physical reads", args(1,1, arg("",lng))),
     245             :  command("profiler", "getDiskWrites", CMDgetDiskWrites, false, "Obtain the number of physical reads", args(1,1, arg("",lng))),
     246             :  command("profiler", "getUserTime", CMDgetUserTime, false, "Obtain the user timing information.", args(1,1, arg("",lng))),
     247             :  command("profiler", "getSystemTime", CMDgetSystemTime, false, "Obtain the user timing information.", args(1,1, arg("",lng))),
     248             :  command("profiler", "cpustats", CMDcpustats, false, "Extract cpu statistics from the kernel", args(5,5, arg("user",lng),arg("nice",lng),arg("sys",lng),arg("idle",lng),arg("iowait",lng))),
     249             :  command("profiler", "cpuload", CMDcpuloadPercentage, false, "Calculate the average cpu load percentage and io waiting times", args(2,7, arg("cycles",int),arg("io",int),arg("user",lng),arg("nice",lng),arg("sys",lng),arg("idle",lng),arg("iowait",lng))),
     250             :  { .imp=NULL }
     251             : };
     252             : #include "mal_import.h"
     253             : #ifdef _MSC_VER
     254             : #undef read
     255             : #pragma section(".CRT$XCU",read)
     256             : #endif
     257         329 : LIB_STARTUP_FUNC(init_profiler_mal)
     258         329 : { mal_module("profiler", NULL, profiler_init_funcs); }

Generated by: LCOV version 1.14