%--------------------------------------------------% % vim: ft=mercury ts=4 sw=4 et %--------------------------------------------------% % Copyright (C) 1994-2011 The University of Melbourne. % Copyright (C) 2014-2016, 2018-2021 The Mercury team. % This file is distributed under the terms specified in COPYING.LIB. %--------------------------------------------------% % % File: benchmarking.m. % Main author: zs. % Stability: medium. % % This module contains predicates that deal with the CPU time requirements % of (various parts of) the program. % %--------------------------------------------------% %--------------------------------------------------% :- module benchmarking. :- interface. :- import_module bool. :- import_module io. :- import_module maybe. % `report_stats/0' is a non-logical procedure intended for use in profiling % the performance of a program. It has the side-effect of reporting % some memory and time usage statistics about the time period since % the last call to report_stats to stderr. % % Note: in Java, this reports usage of the calling thread. You will get % nonsensical results if the previous call to `report_stats' was % from a different thread. % :- impure pred report_stats is det. % `report_full_memory_stats' is a non-logical procedure intended for use % in profiling the memory usage of a program. It has the side-effect % of reporting a full memory profile to stderr. % :- impure pred report_full_memory_stats is det. % report_memory_attribution(Label, Collect, !IO) is a procedure intended % for use in profiling the memory usage by a program. It is supported in % `memprof.gc' grades only, in other grades it is a no-op. It reports a % summary of the objects on the heap to a data file. See ``Using mprof -s % for profiling memory retention'' in the Mercury User's Guide. The label % is for your reference. If Collect is yes, it has the effect of forcing a % garbage collection before building the report. % :- pred report_memory_attribution(string::in, bool::in, io::di, io::uo) is det. :- impure pred report_memory_attribution(string::in, bool::in) is det. % report_memory_attribution(Label, !IO) is the same as % report_memory_attribution/4 above, except that it always forces a % collection (in 'memprof.gc' grades). % :- pred report_memory_attribution(string::in, io::di, io::uo) is det. :- impure pred report_memory_attribution(string::in) is det. % benchmark_det(Pred, In, Out, Repeats, Time) is for benchmarking the det % predicate Pred. We call Pred with the input In and the output Out, and % return Out so that the caller can check the correctness of the % benchmarked predicate. Since most systems do not have good facilities % for measuring small times, the Repeats parameter allows the caller % to specify how many times Pred should be called inside the timed % interval. The number of milliseconds required to execute Pred with input % In this many times is returned as Time. % :- pred benchmark_det(pred(T1, T2), T1, T2, int, int). :- mode benchmark_det(pred(in, out) is det, in, out, in, out) is cc_multi. :- mode benchmark_det(pred(in, out) is cc_multi, in, out, in, out) is cc_multi. % benchmark_func(Func, In, Out, Repeats, Time) does for functions exactly % what benchmark_det does for predicates. % :- pred benchmark_func(func(T1) = T2, T1, T2, int, int). :- mode benchmark_func(func(in) = out is det, in, out, in, out) is cc_multi. % benchmark_det_io(Pred, In, Out, !State, Repeats, Time) is similar to % benchmark_det, except that it is used for benchmarking a det predicate % Pred which destructively updates some unique state State, in addition to % taking the input In and producing the output Out. % State will usually be the I/O state, but it may be some other unique % data structure. % :- pred benchmark_det_io(pred(T1, T2, State, State), T1, T2, State, State, int, int). :- mode benchmark_det_io(pred(in, out, di, uo) is det, in, out, di, uo, in, out) is cc_multi. % benchmark_nondet(Pred, In, Count, Repeats, Time) is for benchmarking % the nondet predicate Pred. benchmark_nondet is similar to benchmark_det, % but it returns only a count of the solutions, rather than solutions % themselves. The number of milliseconds required to generate all % solutions of Pred with input In Repeats times is returned as Time. % :- pred benchmark_nondet(pred(T1, T2), T1, int, int, int). :- mode benchmark_nondet(pred(in, out) is nondet, in, out, in, out) is cc_multi. %--------------------------------------------------% %--------------------------------------------------% % Turn off or on the collection of all profiling statistics. % :- pred turn_off_profiling(io::di, io::uo) is det. :- pred turn_on_profiling(io::di, io::uo) is det. :- impure pred turn_off_profiling is det. :- impure pred turn_on_profiling is det. % Turn off or on the collection of call graph profiling statistics. % :- pred turn_off_call_profiling(io::di, io::uo) is det. :- pred turn_on_call_profiling(io::di, io::uo) is det. :- impure pred turn_off_call_profiling is det. :- impure pred turn_on_call_profiling is det. % Turn off or on the collection of time spent in each procedure % profiling statistics. % :- pred turn_off_time_profiling(io::di, io::uo) is det. :- pred turn_on_time_profiling(io::di, io::uo) is det. :- impure pred turn_off_time_profiling is det. :- impure pred turn_on_time_profiling is det. % Turn off or on the collection of memory allocated in each procedure % profiling statistics. % :- pred turn_off_heap_profiling(io::di, io::uo) is det. :- pred turn_on_heap_profiling(io::di, io::uo) is det. :- impure pred turn_off_heap_profiling is det. :- impure pred turn_on_heap_profiling is det. %--------------------------------------------------% %--------------------------------------------------% % write_out_trace_counts(FileName, MaybeErrorMsg, !IO): % % Write out the trace counts accumulated so far in this program's execution % to FileName. If successful, set MaybeErrorMsg to "no". If unsuccessful, % e.g. because the program wasn't compiled with debugging enabled or % because trace counting isn't turned on, then set MaybeErrorMsg to a "yes" % wrapper around an error message. % :- pred write_out_trace_counts(string::in, maybe(string)::out, io::di, io::uo) is det. %--------------------------------------------------% %--------------------------------------------------% % Place a log message in the threadscope event stream. The event will be % logged as being generated by the current Mercury Engine. This is a no-op % when threadscope is not available. % :- pred log_threadscope_message(string::in, io::di, io::uo) is det. %--------------------------------------------------% %--------------------------------------------------%