This module contains a number of procedures used to perform statistical analysis. The analysis can be divided into three groups:
The procedure perf init initializes the local variables used in the time and counting analysis.
The procedure perf print prints the performance data on the file parameter listing. This procedure prints the binary identifier tree statistics, the results of the time analysis and the results of the counting analysis.
This module exports the enumeration type perf process for the time analysis. Each element of this enumeration type represents one process for which the time usage can be recorded. The two procedures perf start time and perf end time are used to record the time used for the process indicated by the parameter i of type perf process. Each time the procedure perf end time is called for one of the processes, the time difference between this call and the last call to the procedure perf start time for this process is added to the total time recorded for the process.
This module exports the type perf proc for the counting analysis. Each element of this enumeration type represents one process for which counting can be done. The procedure perf nr calls is used to record the counting. Each time this procedure is called the count for the process indicated by the parameter i of type perf proc is incremented.
The binary identifier tree statistics are collected by calling the procedure tree statistics [bintree 5].
This module uses no declarations from other modules.
The following type declaration is exported by this module:
max_level = 51;
The following type declaration is exported by this module:
levels = ARRAY[0..max_level] OF integer; perf_process = (perf_r_o_c_n, perf_r_t_f, perf_r_a_io, perf_r_r_r, perf_2_cl, perf_2_reach, perf_2_term, perf_2_attr, perf_2_e_t, perf_2_trans, perf_2_t_com, perf_3_fl_im, perf_3_mk_nr, perf_3_g_dep, perf_4_pr_dep, perf_4_mk_rel, perf_4_find, perf_g_decl, perf_g_prgr, perf_print_id ); perf_proc = (perf_compare, perf_get_name, perf_insert_name, perf_get_one_char, perf_nextsym, perf_name, perf_expect, perf_back_on_the_rails, perf_error, perf_skip );
The following procedures are exported by the module:
PROCEDURE perf_init;
This procedure initializes the local performances variables. See section 1
PROCEDURE perf_start_time(i : perf_process);
This procedure initializes the start time of process i again. See section 2
PROCEDURE perf_end_time(i : perf_process);
This procedure adds the difference between this call and the last call of perf_start_time with the total time consumed for process i. If there was no previous call to perf start time, the call to perf init is taken. See section 2
PROCEDURE perf_nr_calls(i : perf_proc);
This procedure updates the number of calls of procedure i. See section 3
PROCEDURE perf_print(VAR listing : TEXT);
This procedure prints performance statistics in file listing. See section 1
[ENVIRONMENT ('perform.pen')] MODULE perform(output); (* This module provides a number of procedures to do some performance *) (* analysis. These analysis are divided in tree groups : *) (* - time analysis : to measure the cpu time used for a certain task, *) (* - counting analysis : to count the number of calls to a procedure, *) (* - tree statistics : to give some statistics about the binary tree. *) (* *) (* Time Analysis *) (* *) (* This module exports the type perf_process for the time analysis. *) (* There are two procedures that operate on the members of this enumeration *) (* type, namely perf_start_time and perf_end_time. Every time perf_end_time is*) (* called the time difference between this call and the last call to *) (* perf_start_time is added to the total time used by this process. *) (* *) (* Counting Analysis *) (* *) (* This module exports the type perf_proc for the counting analysis. *) (* The procedure perf_nr_calls adds one to the number of calls for the *) (* member of the enumeration type perf_proc that is given as a parameter at *) (* the calling of this procedure. *) CONST max_level = 51; TYPE levels = ARRAY[0..max_level] OF integer; (* shared with other modules *) perf_process = (perf_r_o_c_n, perf_r_t_f, perf_r_a_io, perf_r_r_r, perf_2_cl, perf_2_reach, perf_2_term, perf_2_attr, perf_2_e_t, perf_2_trans, perf_2_t_com, perf_3_fl_im, perf_3_mk_nr, perf_3_g_dep, perf_4_pr_dep, perf_4_mk_rel, perf_4_find, perf_g_decl, perf_g_prgr, perf_print_id ); perf_proc = (perf_compare, perf_get_name, perf_insert_name, perf_get_one_char, perf_nextsym, perf_name, perf_expect, perf_back_on_the_rails, perf_error, perf_skip ); [HIDDEN] VAR (* local for this module *) perf_begins, perf_total : ARRAY [perf_process] OF integer; perf_calls : ARRAY [perf_proc] OF integer; |
PROCEDURE perf_init; (* This procedure initializes the local performance variables *) VAR i : perf_process; j : perf_proc; now : integer; BEGIN now := clock; FOR i := perf_r_o_c_n TO perf_print_id DO BEGIN perf_begins[i] := now; perf_total[i] := 0 END; FOR j := perf_compare TO perf_skip DO perf_calls[j] := 0; END; PROCEDURE perf_start_time(i : perf_process); (* This procedure initializes the start_time of process i again. *) BEGIN perf_begins[i] := clock; END; PROCEDURE perf_end_time(i : perf_process); (* This procedure adds the difference between this call and the last call *) (* of perf_start_time with the total time consumed for process i. *) (* If there was no previous call to perf_start_time, the call to perf_init *) (* is taken. *) BEGIN perf_total[i] := perf_total[i] + clock - perf_begins[i]; END; PROCEDURE perf_nr_calls(i : perf_proc); (* This procedure updates the number of calls of procedure i. A message *) (* on the terminal is given when the number of calls exceeds max_call_nr *) (* (which is very rare). *) CONST max_call_nr = 10000000; BEGIN IF perf_calls[i] < max_call_nr THEN perf_calls[i] := succ(perf_calls[i]) END; |
[EXTERNAL,HIDDEN] PROCEDURE tree_statistics( VAR nr_of_nodes, min_depth, max_depth : integer ; VAR average_depth : real ; VAR count : levels); (* This procedure returns the tree statistics, where nr_of_nodes contains *) (* the number of nodes in the binary tree, min_depth the depth with the *) (* first empty nodes in it, max_depth the depth with the last filled nodes *) (* in it. Average_depth will contain the average depth of the nodes. Count *) (* is an array in which the number of nodes on each depth are recorded. *) (*--------------------------------------------------------------------------*) (* REMARK:this procedure has to be in a module that inherits this module, *) (* because the type "levels" is needed. *) EXTERN; PROCEDURE perf_print(VAR listing : TEXT); (* This procedure prints performance statistics in file listing *) VAR number_of , nr_of_nodes , min_depth , max_depth : integer; average_depth : real; depth, i : integer; j : perf_process; k : perf_proc; count : levels; PROCEDURE pr_t(txt : VARYING[S] OF char; j : perf_process); (* This procedure prints the start time and the end time of process j *) BEGIN IF perf_total[j] > 0 THEN writeln(listing, txt, ' : ', perf_total[j]/1000 : 8 : 5, ' second(s)'); END; PROCEDURE pr_c(txt : VARYING[S] OF char; k : perf_proc); (* This procedure prints the number of calls of procedure k *) BEGIN IF perf_calls[k] > 0 THEN IF perf_calls[k] = 1 THEN writeln(listing, txt, perf_calls[k], ' time called') ELSE writeln(listing, txt, perf_calls[k], ' times called'); END; BEGIN (* of perf_print *) page(listing); writeln(listing); writeln(listing, ' PERFORMANCE STATISTICS'); writeln(listing); writeln(listing); (* Statistics of the binary tree *) tree_statistics(nr_of_nodes, min_depth, max_depth, average_depth, count); writeln(listing, ' - number of nodes in binary tree :', nr_of_nodes); writeln(listing, ' - minimum depth of binary tree :', min_depth); writeln(listing, ' - maximum depth of binary tree :', max_depth); writeln(listing, ' - average depth of binary tree :', average_depth); writeln(listing); depth := max_depth; IF depth >= max_level THEN depth := pred(max_level); number_of := 1; FOR i := 0 TO pred(depth) DO BEGIN writeln(listing, ' - number of nodes at depth ', i:2, ' ':4, count[i]:4, ' (', count[i]/number_of*100:6:2, '%)'); number_of := number_of * 2 END; writeln(listing); (* Statistics of the runtimes *) writeln(listing, 'Runtimes:'); writeln(listing); writeln(listing, 'Pass 1 : scanning and parsing'); pr_t( ' reading: OPTIONS, CLASSES and NODES ', perf_r_o_c_n); pr_t( ' reading: TYPES and FUNCTIONS ', perf_r_t_f); pr_t( ' reading: ATTRIBUTES and IN/OUTPUT ', perf_r_a_io); pr_t( ' reading: RULES and ROOT ', perf_r_r_r); writeln(listing); writeln(listing, 'Pass 2 : semantic checks and transformation'); pr_t( ' testing: classes defined ', perf_2_cl); pr_t( ' testing: reachability ', perf_2_reach); pr_t( ' testing: termination ', perf_2_term); pr_t( ' testing: attributes ', perf_2_attr); pr_t( ' transform: generate empty trees ', perf_2_e_t); pr_t( ' transform: fill assignment trees ', perf_2_trans); pr_t( ' transform: test complete filled ', perf_2_t_com); writeln(listing); writeln(listing, 'Pass 3 : generate dependency graph'); pr_t( ' test flat implementable ', perf_3_fl_im); pr_t( ' make numbering for pairs ', perf_3_mk_nr); pr_t( ' generate dependencies ', perf_3_g_dep); writeln(listing); writeln(listing, 'Pass 4 : find Simple Multi-Pass solution'); pr_t( ' print dependencies ', perf_4_pr_dep); pr_t( ' make relations ', perf_4_mk_rel); pr_t( ' find with relations the solution ', perf_4_find); writeln(listing); writeln(listing, 'Pass 5 : Pascal program generation'); pr_t( ' generate: declarations ', perf_g_decl); pr_t( ' generate: procedures and body ', perf_g_prgr); writeln(listing); writeln(listing, 'Finals'); pr_t( ' print: binary tree ', perf_print_id); writeln(listing); writeln(listing); (* Statistics of the number of calls *) writeln(listing, 'Number of calls:'); pr_c( ' - COMPARE ', perf_compare); pr_c( ' - GET_NAME ', perf_get_name); pr_c( ' - INSERT_NAME ', perf_insert_name); pr_c( ' - GET_ONE_CHAR ', perf_get_one_char); pr_c( ' - NEXTSYM ', perf_nextsym); pr_c( ' - NAME ', perf_name); pr_c( ' - EXPECT ', perf_expect); pr_c( ' - BACK_ON_THE_RAILS ', perf_back_on_the_rails); pr_c( ' - ERROR ', perf_error); pr_c( ' - SKIP ', perf_skip); writeln(listing) END; END. |
My life as a hacker | My home page