Skip to content

Commit

Permalink
Using the standard deviation to identify outliers
Browse files Browse the repository at this point in the history
  • Loading branch information
cpey committed Nov 16, 2024
1 parent 134a9cd commit 1897155
Showing 1 changed file with 24 additions and 4 deletions.
28 changes: 24 additions & 4 deletions chipsec/modules/tools/smm/smm_ptr.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
import struct
import sys
import time
import math

from chipsec.module_common import BaseModule
from chipsec.library.returncode import ModuleResult
Expand Down Expand Up @@ -147,6 +148,7 @@
# Defines the time percentage increase at which the SMI call is considered to
# be long-running
OUTLIER_THRESHOLD = 10
OUTLIER_STD_DEV = 2

# Scan mode delay before SMI calls
SCAN_MODE_DELAY = 0.01
Expand Down Expand Up @@ -205,6 +207,12 @@ def __init__(self):
self.outliers_hist = 0
self.records = {'deltas': [], 'times': []}
self.msr_count = self.get_msr_count()
self.stdev = 0
self.stdev_hist = 0
self.m2 = 0
self.m2_hist = 0
self.difference = 0
self.difference_hist = 0

def get_msr_count(self):
cpu = 0
Expand Down Expand Up @@ -252,6 +260,7 @@ def add(self, duration, time, code, data, gprs, confirmed=False):
self.records['times'].append(time)
self.acc_smi_duration += duration
self.acc_smi_num += 1
self.update_stdev(duration)
if not outlier:
if duration > self.max.duration:
self.max.update(duration, code, data, gprs.copy())
Expand All @@ -272,19 +281,30 @@ def avg(self):
self.acc_smi_duration = 0
self.acc_smi_num = 0

def update_stdev(self, value):
self.difference = value - self.avg_smi_duration
self.difference_hist = value - self.hist_smi_duration
self.avg()
self.m2 += self.difference * (value - self.avg_smi_duration)
self.m2_hist = self.difference_hist * (value - self.hist_smi_duration)
variance = self.m2 / self.avg_smi_num
variance_hist = self.m2_hist / self.hist_smi_num
self.stdev = math.sqrt(variance)
self.stdev_hist = math.sqrt(variance_hist)

def is_slow_outlier(self, value):
ret = False
if self.avg_smi_duration and value > self.avg_smi_duration * (1 + OUTLIER_THRESHOLD / 100):
if value > self.avg_smi_duration + OUTLIER_STD_DEV * self.stdev:
ret = True
if self.hist_smi_duration and value > self.hist_smi_duration * (1 + OUTLIER_THRESHOLD / 100):
if value > self.hist_smi_duration + OUTLIER_STD_DEV * self.stdev_hist:
ret = True
return ret

def is_fast_outlier(self, value):
ret = False
if self.avg_smi_duration and value < self.avg_smi_duration * (1 - OUTLIER_THRESHOLD / 100):
if value < self.avg_smi_duration - OUTLIER_STD_DEV * self.stdev:
ret = True
if self.hist_smi_duration and value < self.hist_smi_duration * (1 - OUTLIER_THRESHOLD / 100):
if value < self.hist_smi_duration - OUTLIER_STD_DEV * self.stdev_hist:
ret = True
return ret

Expand Down

0 comments on commit 1897155

Please sign in to comment.