Skip to content

Commit d9c4895

Browse files
committed
Using the standard deviation to identify outliers
1 parent 134a9cd commit d9c4895

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

chipsec/modules/tools/smm/smm_ptr.py

+23-4
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
# Defines the time percentage increase at which the SMI call is considered to
148148
# be long-running
149149
OUTLIER_THRESHOLD = 10
150+
OUTLIER_STD_DEV = 2
150151

151152
# Scan mode delay before SMI calls
152153
SCAN_MODE_DELAY = 0.01
@@ -205,6 +206,12 @@ def __init__(self):
205206
self.outliers_hist = 0
206207
self.records = {'deltas': [], 'times': []}
207208
self.msr_count = self.get_msr_count()
209+
self.stdev = 0
210+
self.stdev_hist = 0
211+
self.m2 = 0
212+
self.m2_hist = 0
213+
self.difference = 0
214+
self.difference_hist = 0
208215

209216
def get_msr_count(self):
210217
cpu = 0
@@ -252,6 +259,7 @@ def add(self, duration, time, code, data, gprs, confirmed=False):
252259
self.records['times'].append(time)
253260
self.acc_smi_duration += duration
254261
self.acc_smi_num += 1
262+
self.update_stdev(duration)
255263
if not outlier:
256264
if duration > self.max.duration:
257265
self.max.update(duration, code, data, gprs.copy())
@@ -272,19 +280,30 @@ def avg(self):
272280
self.acc_smi_duration = 0
273281
self.acc_smi_num = 0
274282

283+
def update_stdev(self, value):
284+
self.difference = value - self.avg_smi_duration
285+
self.difference_hist = value - self.hist_smi_duration
286+
self.avg()
287+
self.m2 += self.difference * (value - self.avg_smi_duration)
288+
self.m2_hist = self.difference_hist * (value - self.hist_smi_duration)
289+
variance = self.m2 / self.avg_smi_num
290+
variance_hist = self.m2_hist / self.hist_smi_num
291+
self.stdev = math.sqrt(variance)
292+
self.stdev_hist = math.sqrt(variance_hist)
293+
275294
def is_slow_outlier(self, value):
276295
ret = False
277-
if self.avg_smi_duration and value > self.avg_smi_duration * (1 + OUTLIER_THRESHOLD / 100):
296+
if value > self.avg_smi_duration + OUTLIER_STD_DEV * self.stdev:
278297
ret = True
279-
if self.hist_smi_duration and value > self.hist_smi_duration * (1 + OUTLIER_THRESHOLD / 100):
298+
if value > self.hist_smi_duration + OUTLIER_STD_DEV * self.stdev_hist:
280299
ret = True
281300
return ret
282301

283302
def is_fast_outlier(self, value):
284303
ret = False
285-
if self.avg_smi_duration and value < self.avg_smi_duration * (1 - OUTLIER_THRESHOLD / 100):
304+
if value < self.avg_smi_duration - OUTLIER_STD_DEV * self.stdev:
286305
ret = True
287-
if self.hist_smi_duration and value < self.hist_smi_duration * (1 - OUTLIER_THRESHOLD / 100):
306+
if value < self.hist_smi_duration - OUTLIER_STD_DEV * self.stdev_hist:
288307
ret = True
289308
return ret
290309

0 commit comments

Comments
 (0)