1 | /** |
2 | * |
3 | */ |
4 | package de.uka.ipd.sdq.tcfmoop.terminationcriteria; |
5 | |
6 | import java.lang.management.ManagementFactory; |
7 | import java.lang.management.ThreadMXBean; |
8 | |
9 | import org.opt4j.core.Archive; |
10 | import org.opt4j.core.Population; |
11 | |
12 | import de.uka.ipd.sdq.tcfmoop.config.ElapsedTimeConfig; |
13 | import de.uka.ipd.sdq.tcfmoop.config.IConfiguration; |
14 | import de.uka.ipd.sdq.tcfmoop.config.ElapsedTimeConfig.TimeType; |
15 | import de.uka.ipd.sdq.tcfmoop.outputtree.Node; |
16 | import de.uka.ipd.sdq.tcfmoop.outputtree.Node.NodeType; |
17 | |
18 | /** |
19 | * @author Atanas Dimitrov |
20 | * |
21 | */ |
22 | public class ElapsedTimeCriterion extends AbstractTerminationCriterion { |
23 | |
24 | //The minimum time the optimization is allowed to run |
25 | private long executionInterval; |
26 | private long elapsedTime; |
27 | private TimeType timeType; |
28 | private long startTime; |
29 | //Required for the check whether CPU time measurement is possible |
30 | private ThreadMXBean threadMXBean; |
31 | private boolean isCPUTimeMeasuringSupported; |
32 | |
33 | //OutputNodes |
34 | //static |
35 | @SuppressWarnings("unused") |
36 | private Node timeTypeNode; |
37 | //dynamic |
38 | private Node executionTimeNode; |
39 | private Node remainingTimeNode; |
40 | |
41 | public ElapsedTimeCriterion(IConfiguration conf, Population population, |
42 | Archive archive){ |
43 | |
44 | super(conf, population, archive); |
45 | |
46 | if((conf instanceof ElapsedTimeConfig) && conf.validateConfiguration()){ |
47 | this.executionInterval = ((ElapsedTimeConfig)(conf)).getExecutionInterval(); |
48 | this.timeType = ((ElapsedTimeConfig)(conf)).getTimeType(); |
49 | this.startTime = System.currentTimeMillis(); |
50 | if(this.timeType.equals(TimeType.CPU_TIME)){ |
51 | this.threadMXBean = ManagementFactory.getThreadMXBean(); |
52 | if(this.threadMXBean.isThreadCpuTimeSupported()){ |
53 | if(!this.threadMXBean.isThreadCpuTimeEnabled()){ |
54 | this.threadMXBean.setThreadCpuTimeEnabled(true); |
55 | } |
56 | this.isCPUTimeMeasuringSupported = true; |
57 | }else{ |
58 | this.isCPUTimeMeasuringSupported = false; |
59 | } |
60 | } |
61 | }else{ |
62 | throw new RuntimeException("ElapsedTimeCriterion.initialize: " + |
63 | "wrong or invalid configuration object"); |
64 | } |
65 | initializeOutputTree(); |
66 | |
67 | } |
68 | |
69 | private void initializeOutputTree(){ |
70 | this.outputInformation.updateValue("Elapsed Time"); |
71 | this.outputInformation.getChildren().clear(); |
72 | |
73 | if(timeType.equals(TimeType.CPU_TIME)){ |
74 | if(!this.isCPUTimeMeasuringSupported){ |
75 | this.timeTypeNode = this.outputInformation.addChild("Time Type: Cannot Meassure CPU Time. Measuring USER Time instead.", NodeType.PARAMETER); |
76 | }else{ |
77 | this.timeTypeNode = this.outputInformation.addChild("Time Type: CPU Time", NodeType.PARAMETER); |
78 | } |
79 | }else{ |
80 | this.timeTypeNode = this.outputInformation.addChild("Time Type: USER Time", NodeType.PARAMETER); |
81 | } |
82 | |
83 | this.executionTimeNode = this.outputInformation.addChild("Minimum Execution Time: " + this.executionInterval + " ms", NodeType.PARAMETER); |
84 | this.remainingTimeNode = this.outputInformation.addChild("Elapsed Time: " + this.elapsedTime + " ms", NodeType.PARAMETER); |
85 | this.outputInformation.getChildren().add(this.suggestedStop); |
86 | } |
87 | |
88 | /** |
89 | * {@inheritDoc} |
90 | * Implements the ElapsedTime Criterion: This criterion measures either the CPU time (if possible) |
91 | * or the Clock time. When the execution time goes past a certain value, the criterion will report |
92 | * that the optimization should be stopped. |
93 | */ |
94 | @Override |
95 | public void evaluateImpl(int iteration, long currentTime) { |
96 | if(timeType.equals(TimeType.CPU_TIME)){ |
97 | if(this.isCPUTimeMeasuringSupported){ |
98 | this.elapsedTime = (threadMXBean.getThreadCpuTime(Thread.currentThread().getId())/1000000); |
99 | }else{ |
100 | this.elapsedTime = currentTime - this.startTime; |
101 | } |
102 | }else if(this.timeType.equals(TimeType.USER_TIME)){ |
103 | this.elapsedTime = currentTime - this.startTime; |
104 | } |
105 | |
106 | if(this.elapsedTime > this.executionInterval){ |
107 | this.evaluationResult = true; |
108 | }else{ |
109 | this.evaluationResult = false; |
110 | } |
111 | } |
112 | |
113 | /** |
114 | * {@inheritDoc} |
115 | */ |
116 | @Override |
117 | public void updateOutputInformation(){ |
118 | this.executionTimeNode.updateValue("Minimum Execution Time: " + this.executionInterval + " ms"); |
119 | this.remainingTimeNode.updateValue("Elapsed Time: " + this.elapsedTime + " ms"); |
120 | } |
121 | |
122 | } |