Added bandwidth root cause analysis
This commit is contained in:
@@ -59,7 +59,6 @@ def trans_with_max_response_latency(connection):
|
||||
result = cursor.fetchone()
|
||||
return result[0]
|
||||
|
||||
|
||||
@metric
|
||||
def memory_active(connection):
|
||||
cursor = connection.cursor()
|
||||
@@ -68,7 +67,6 @@ def memory_active(connection):
|
||||
clk, unit = getClock(connection)
|
||||
return (active[0]/clk)
|
||||
|
||||
|
||||
@metric
|
||||
def memory_total(connection):
|
||||
cursor = connection.cursor()
|
||||
@@ -109,7 +107,6 @@ def memory_idle(connection):
|
||||
cursor.execute(query)
|
||||
|
||||
query = """
|
||||
|
||||
SELECT
|
||||
sum(b.BeginRequest - a.EndResponse) AS idle
|
||||
FROM
|
||||
@@ -134,6 +131,155 @@ def memory_delayed(connection):
|
||||
idle = memory_idle(connection)
|
||||
return total - active - idle
|
||||
|
||||
def check_miss(connection, ID):
|
||||
cursor = connection.cursor()
|
||||
query = """SELECT * FROM phases WHERE PhaseName == "ACT" AND Transact = {};""".format(ID)
|
||||
cursor.execute(query)
|
||||
result = cursor.fetchone()
|
||||
if(result != None) :
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def check(connection, gapBegin, gapEnd, b, e):
|
||||
cursor = connection.cursor()
|
||||
query = """SELECT Command FROM Transactions WHERE ID = {};""".format(gapBegin)
|
||||
cursor.execute(query)
|
||||
begin = cursor.fetchone()[0]
|
||||
query = """SELECT Command FROM Transactions WHERE ID = {};""".format(gapEnd)
|
||||
cursor.execute(query)
|
||||
end = cursor.fetchone()[0]
|
||||
return (begin == b and end == e)
|
||||
|
||||
@metric
|
||||
def delayed_reasons(connection):
|
||||
cursor = connection.cursor()
|
||||
|
||||
# Create a table with sorted Datastrobes:
|
||||
# (RowNum, ID, Begin, End)
|
||||
query = """ DROP TABLE IF EXISTS dataStrobesInOrder; """
|
||||
cursor.execute(query)
|
||||
|
||||
query = """
|
||||
CREATE TEMPORARY TABLE dataStrobesInOrder AS
|
||||
SELECT
|
||||
ROW_NUMBER () OVER (ORDER BY t.DataStrobeBegin) RowNum,
|
||||
t.ID as ID,
|
||||
t.DataStrobeBegin as Begin,
|
||||
t.DataStrobeEnd as End
|
||||
|
||||
FROM
|
||||
Transactions t
|
||||
WHERE
|
||||
t.DataStrobeBegin <> 0 AND
|
||||
t.DataStrobeEnd <> 0;
|
||||
"""
|
||||
cursor.execute(query)
|
||||
|
||||
# Create a table with phases sorted by BeginResponse:
|
||||
# (RowNum, BeginRequest, EndRequest, BeginResponse, EndResponse, ID)
|
||||
query = """ DROP TABLE IF EXISTS phasesInOrder; """
|
||||
cursor.execute(query)
|
||||
|
||||
query = """
|
||||
CREATE TEMPORARY TABLE phasesInOrder AS
|
||||
SELECT
|
||||
ROW_NUMBER () OVER (ORDER BY q.PhaseBegin) RowNum,
|
||||
p.PhaseBegin AS BeginRequest,
|
||||
p.PhaseEnd AS EndRequest,
|
||||
q.PhaseBegin AS BeginResponse,
|
||||
q.PhaseEnd AS EndResponse,
|
||||
p.Transact AS ID
|
||||
FROM
|
||||
Phases p,
|
||||
Phases q
|
||||
WHERE
|
||||
p.PhaseName = "REQ"
|
||||
AND q.PhaseName = "RESP"
|
||||
AND p.Transact = q.Transact;
|
||||
"""
|
||||
cursor.execute(query)
|
||||
|
||||
# Create a table with transaction IDs that start a idle time:
|
||||
# (ID)
|
||||
query = """ DROP TABLE IF EXISTS idleGaps; """
|
||||
cursor.execute(query)
|
||||
|
||||
query = """
|
||||
CREATE TEMPORARY TABLE idleGaps AS
|
||||
SELECT a.ID AS ID
|
||||
FROM phasesInOrder AS a, phasesInOrder AS b
|
||||
WHERE
|
||||
(a.RowNum)=(b.RowNum-1) AND
|
||||
b.BeginRequest > a.EndResponse;
|
||||
"""
|
||||
cursor.execute(query)
|
||||
|
||||
# Create a table which features IDs that form gaps on the databus:
|
||||
# (gapBeginID, gapEndID)
|
||||
query = """ DROP TABLE IF EXISTS delayedDataBusGaps; """
|
||||
cursor.execute(query)
|
||||
|
||||
query = """
|
||||
CREATE TEMPORARY TABLE delayedDataBusGaps AS
|
||||
SELECT a.ID AS gapBeginID, b.ID AS gapEndID
|
||||
FROM
|
||||
dataStrobesInOrder a,
|
||||
dataStrobesInOrder b
|
||||
|
||||
WHERE
|
||||
(a.RowNum) = (b.RowNum-1) AND
|
||||
b.Begin > a.End AND
|
||||
a.ID not in (SELECT ID FROM idleGaps);
|
||||
"""
|
||||
cursor.execute(query)
|
||||
|
||||
query = """ SELECT * FROM delayedDataBusGaps; """;
|
||||
cursor.execute(query)
|
||||
|
||||
records = cursor.fetchall()
|
||||
|
||||
RR_Miss = 0
|
||||
WW_Miss = 0
|
||||
RW_Hit = 0
|
||||
RW_Miss = 0
|
||||
WR_Hit = 0
|
||||
WR_Miss = 0
|
||||
e = 0
|
||||
result = ""
|
||||
|
||||
for row in records:
|
||||
gapBegin = row[0]
|
||||
gapEnd = row[1]
|
||||
|
||||
if (check(connection, gapBegin, gapEnd, "R", "R") and check_miss(connection, gapEnd)):
|
||||
RR_Miss += 1
|
||||
elif(check(connection, gapBegin, gapEnd, "W", "W") and check_miss(connection, gapEnd)):
|
||||
WW_Miss += 1
|
||||
elif(check(connection, gapBegin, gapEnd, "R", "W") and (not check_miss(connection, gapEnd))):
|
||||
RW_Hit += 1
|
||||
elif(check(connection, gapBegin, gapEnd, "R", "W") and check_miss(connection, gapEnd)):
|
||||
RW_Miss += 1
|
||||
elif(check(connection, gapBegin, gapEnd, "W", "R") and (not check_miss(connection, gapEnd))):
|
||||
WR_Hit += 1
|
||||
elif(check(connection, gapBegin, gapEnd, "W", "R") and check_miss(connection, gapEnd)):
|
||||
WR_Miss += 1
|
||||
else:
|
||||
print ("ERROR: This should not happen")
|
||||
exit(-1)
|
||||
|
||||
total = RR_Miss + WW_Miss + RW_Hit + RW_Miss + WR_Hit + WR_Miss
|
||||
|
||||
RR_Miss /= total
|
||||
WW_Miss /= total
|
||||
RW_Hit /= total
|
||||
RW_Miss /= total
|
||||
WR_Hit /= total
|
||||
WR_Miss /= total
|
||||
|
||||
result = "RRM: {}, WWM: {}, RWH: {}, RWM: {}, WRH: {}, WRM: {}".format(RR_Miss, WW_Miss, RW_Hit, RW_Miss, WR_Hit, WR_Miss);
|
||||
return result
|
||||
|
||||
@metric
|
||||
def memory_idle_in_percent(connection):
|
||||
total = memory_total(connection)
|
||||
|
||||
Reference in New Issue
Block a user