1 /*
2  * @(#) $Id: BenchCommand.java,v 1.5 2003/07/08 08:13:53 pankaj Exp $
3  *
4  * Copyright (c) 2002-03 by Pankaj Kumar (http://www.pankaj-k.net). 
5  * All rights reserved.
6  *
7  * The license governing the use of this file can be found in the 
8  * root directory of the containing software.
9  */
10package org.jstk.crypt;
11
12import java.util.*;
13import java.io.*;
14import org.jstk.*;
15
16public class BenchCommand extends JSTKCommandAdapter{
17    private static HashMap defaults = new HashMap();
18    static {
19        defaults.put("cmdfile", "bin/ctbench.cmds");
20        defaults.put("runcount", "1");
21        defaults.put("warmuptime", "60");
22        defaults.put("loopcount", "0");
23        defaults.put("minimize_et", "true");
24    }
25    public String briefDescription(){
26        return "benchmarks crypttool commands";
27    }
28    public String optionsDescription(){
29        return
30            "  -cmdfile <file>     : read commands from this file.\n" +
31            "  -warmuptime <wt>    : minimum JVM warmup time in seconds.\n" +
32            "  -runcount <rc>      : how many runs?.\n" +
33            "  -minmize_et         : compute loopcount to minimize execution time.\n" +
34            "  -loopcount <lc>     : how many loops for each command within a run.\n";
35    }
36
37    public String[] useForms(){
38        String[] useForms = { "[-provider <provider>] [-info] [-props] [-csinfo]" };
39        return useForms;
40    }
41    public String[] sampleUses(){
42        String[] uses = {
43            "",
44            "-cmdfile test.cmds",
45            "-warmuptime 900 -minimize_et",
46            "-runcount 5 -loopcount 5"
47        };
48        return uses;
49    }
50
51    private String[][] parseCmdFile(String cmdfile) throws IOException{
52        BufferedReader br = new BufferedReader(
53            new InputStreamReader(new FileInputStream(cmdfile)));
54
55        //Create and initialize the tokenizer so that it can read the command script file.
56        StreamTokenizer st = new StreamTokenizer(br);
57        st.resetSyntax();
58        st.whitespaceChars('\u0000', '\u0020');
59        st.wordChars('!', '~');
60        st.commentChar('#');
61        st.quoteChar('"');
62        st.slashSlashComments(true);
63        st.slashStarComments(true);
64        st.eolIsSignificant(true);
65
66        Vector cmdLines = new Vector();
67        Vector cmdWords = null;
68        int tok;
69        do {
70            tok = st.nextToken();
71            if (tok == st.TT_WORD){
72                if (cmdWords == null)
73                    cmdWords = new Vector();
74                cmdWords.add(st.sval);
75            } else if ((tok == st.TT_EOL)||(tok == st.TT_EOF)){
76                if (cmdWords == null)
77                    continue;
78                String[] cmdArgs = new String[cmdWords.size()];
79                for (int i = 0; i < cmdWords.size(); i++)
80                    cmdArgs[i] = (String)cmdWords.elementAt(i);
81                cmdWords = null;
82                cmdLines.add(cmdArgs);
83            }
84        } while (tok != st.TT_EOF);
85        String[][] cmds = new String[cmdLines.size()][];
86        for (int i = 0; i < cmdLines.size(); i++)
87            cmds[i] = (String[])cmdLines.elementAt(i);
88        return cmds;
89    }
90
91    public Object execute(JSTKArgs args) throws JSTKException{
92        try {
93            args.setDefaults(defaults);
94            String cmdfile = args.get("cmdfile");
95            boolean minimize_et = Boolean.valueOf(args.get("minimize_et")).booleanValue();
96            int warmuptime = Integer.parseInt(args.get("warmuptime"));
97            int runcount = Integer.parseInt(args.get("runcount"));
98            int loopcount = Integer.parseInt(args.get("loopcount"));
99
00            // Parse the commands script file.
01            System.out.print("Parsing the command file \"" + cmdfile + "\" ... ");
02            String[][] cmdLines = parseCmdFile(cmdfile);
03            System.out.println(" ... done.");
04
05            JSTKCommand[] cmds = new JSTKCommand[cmdLines.length];
06            JSTKOptions[] optsArray = new JSTKOptions[cmdLines.length];
07            long[] cmdExecTimeArray = new long[cmdLines.length];
08            int[] loopcountArray = new int[cmdLines.length];
09
10            // Intialize JSTKCommand and JSTKOption objects.
11            System.out.print("Intializing ... ");
12            for (int i = 0; i < cmds.length; i++){
13                String cmdString = cmdLines[i][0];
14                cmds[i] = (JSTKCommand)CryptTool.cmds.get(cmdString);
15                if (cmds[i] == null){   // Unknown command.
16                    return new JSTKResult(null, false,
17                        "Unknown Command: " + cmdString + ". Aborting ...");
18                }
19                optsArray[i] = new JSTKOptions();
20                optsArray[i].parse(cmdLines[i], 1);
21            }
22            System.out.println(" ... done.");
23
24            // Validation round.
25            System.out.println("Validating arguments ... ");
26            for (int i = 0; i < cmds.length; i++){
27                System.out.print("Running command[" + i + "]:");
28                for (int j = 0; j < cmdLines[i].length; j++)
29                    System.out.print(" " + cmdLines[i][j]);
30                System.out.print(" ... ");
31
32                JSTKResult res  = (JSTKResult)cmds[i].execute(optsArray[i]);
33
34                if (!res.isSuccess()){
35                    return new JSTKResult(null, false,
36                        "Command execution failed: " + cmds[i] + ". reason: " + res.getText() + ". Aborting ...");
37                } else {
38                    System.out.println(" ... succeeded.");
39                    System.out.println("Result: " + res.getText());
40                }
41            }
42            System.out.println(" ... done.");
43
44            // Caliberation round.
45            System.out.println("Caliberating ... ");
46            for (int i = 0; i < cmds.length; i++){
47                long st = System.currentTimeMillis();
48                JSTKResult res  = (JSTKResult)cmds[i].execute(optsArray[i]);
49                cmdExecTimeArray[i] = System.currentTimeMillis() - st;
50                System.out.println("Execution Time[" + i + "]: " + cmdExecTimeArray[i] +
51                    " milli secs.");
52            }
53            System.out.println(" ... done.");
54
55            // Warmup round.
56            System.out.println("Estimated warmup Time: " + warmuptime + " secs.");
57            System.out.println("Warming up ... ");
58            long st = System.currentTimeMillis();
59            for (int i = 0; i < cmds.length; i++){
60                long timeForCmd = (long)(warmuptime*1000.0)/cmds.length;
61                if (cmdExecTimeArray[i] == 0){
62                    loopcountArray[i] = 100;
63                } else {
64                    loopcountArray[i] = (int)(timeForCmd/cmdExecTimeArray[i]);
65                }
66
67                for (int l = 0; l < loopcountArray[i]; l++){
68                    JSTKResult res  = (JSTKResult)cmds[i].execute(optsArray[i]);
69                    if (!res.isSuccess()){
70                        return new JSTKResult(null, false,
71                            "Command execution failed: " + cmds[i] + ". reason: " + res.getText() + ". Aborting ...");
72                    }
73                }
74            }
75            long et = System.currentTimeMillis() - st;
76            System.out.println(" ... done.");
77            System.out.println("Actual warmup Time: " + ((double)et/1000.0) + " secs.");
78
79            // Measurement Round
80            System.out.println("Measuring ... ");
81            for (int r = 0; r < runcount; r++){
82                System.out.println("Round# ::" + r);
83                for (int i = 0; i < cmds.length; i++){
84                    long timeForCmd = 6000; // Each command should run for at least 6 secs.
85                    if (loopcount != 0){
86                        loopcountArray[i] = loopcount;
87                    } else if (cmdExecTimeArray[i] == 0){
88                        loopcountArray[i] = 1000;   // Fixed loopcount
89                    } else {
90                        loopcountArray[i] = (int)(timeForCmd/cmdExecTimeArray[i]) + 1;
91                    }
92System.out.println("loopcountArray[" + i + "] = " + loopcountArray[i]);
93                    cmds[i].getPerfData().reset();
94                    long st0 = System.currentTimeMillis();
95                    for (int l = 0; l < loopcountArray[i]; l++){
96                        JSTKResult res  = (JSTKResult)cmds[i].execute(optsArray[i]);
97                        if (!res.isSuccess()){
98                            return new JSTKResult(null, false,
99                                "Command execution failed: " + cmds[i] + ". reason: " + res.getText() + ". Aborting ...");
00                        }
01                    }
02                    cmdExecTimeArray[i] = System.currentTimeMillis() - st0;
03
04                    System.out.println("Cmd# ::" + i + ", Loops: " + loopcountArray[i] +
05                        ", Tot. Time: " + cmdExecTimeArray[i] + " ms." + ", Avg. Time: " +
06                        ((double)cmdExecTimeArray[i]/loopcountArray[i]) + " ms.");
07                    cmds[i].getPerfData().store(System.out);
08                }
09            }
10
11            return new JSTKResult(null, true, "done");
12        } catch (Exception exc){
13            throw new JSTKException("BenchCommand execution failed", exc);
14        }
15    }
16
17    public static void main(String[] args) throws Exception {
18        JSTKOptions opts = new JSTKOptions();
19        opts.parse(args, 0);
20        BenchCommand benchCmd = new BenchCommand();
21        JSTKResult result = (JSTKResult)benchCmd.execute(opts);
22        System.out.println(result.getText());
23    }
24}