Adapt metrics to new DB format.
This commit is contained in:
@@ -140,25 +140,26 @@ def getControllerThread(connection):
|
||||
|
||||
def get_phase_occurrences(connection, phase):
|
||||
cursor = connection.cursor()
|
||||
query = "select count(*) from Phases where PhaseName = :phase"
|
||||
query = "SELECT count(*) FROM Phases WHERE PhaseName = :phase"
|
||||
cursor.execute(query, {"phase": phase})
|
||||
r = cursor.fetchone()
|
||||
cnt = r[0]
|
||||
if (cnt is None):
|
||||
if cnt is None:
|
||||
cnt = 0
|
||||
return cnt
|
||||
|
||||
|
||||
def get_total_time_in_phase(connection, phase):
|
||||
cursor = connection.cursor()
|
||||
query = "select sum(PhaseEnd - PhaseBegin) / 1000 from Phases where PhaseName = :phase"
|
||||
query = "SELECT SUM(PhaseEnd - PhaseBegin) / 1000 FROM Phases WHERE PhaseName = :phase"
|
||||
cursor.execute(query, {"phase": phase})
|
||||
time = cursor.fetchone()
|
||||
totalTime = time[0]
|
||||
if (totalTime is None):
|
||||
if totalTime is None:
|
||||
totalTime = 0.0
|
||||
return totalTime
|
||||
|
||||
|
||||
def getCommandLengthForPhase(connection, phase):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("SELECT " + phase + " FROM CommandLengths")
|
||||
|
||||
@@ -21,8 +21,7 @@ def threadMetric(function):
|
||||
def getThreads(connection):
|
||||
cthread = getControllerThread(connection)
|
||||
cursor = connection.cursor()
|
||||
query = "SELECT DISTINCT(TThread) FROM transactions WHERE TThread != " + str(cthread) + " ORDER BY TThread"
|
||||
cursor.execute(query)
|
||||
cursor.execute("SELECT DISTINCT(Thread) FROM Transactions WHERE Thread != " + str(cthread) + " ORDER BY Thread")
|
||||
result = []
|
||||
for currentRow in cursor:
|
||||
result.append(currentRow[0])
|
||||
@@ -32,10 +31,11 @@ def getThreads(connection):
|
||||
@metric
|
||||
def trace_length_in_ns(connection):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(""" SELECT max(PhaseEnd)/1000 FROM PHASES; """)
|
||||
cursor.execute("SELECT MAX(PhaseEnd) / 1000 FROM Phases")
|
||||
result = cursor.fetchone()
|
||||
return result[0]
|
||||
|
||||
|
||||
@metric
|
||||
def command_bus_utilisation_in_percent(connection):
|
||||
cursor = connection.cursor()
|
||||
@@ -75,7 +75,7 @@ def command_bus_utilisation_in_percent(connection):
|
||||
ON Phases.PhaseName = CommandLengths.Command
|
||||
""")
|
||||
util = cursor.fetchone()[0]
|
||||
if (util is None):
|
||||
if util is None:
|
||||
util = 0
|
||||
|
||||
clk, _ = getClock(connection)
|
||||
@@ -83,142 +83,133 @@ def command_bus_utilisation_in_percent(connection):
|
||||
commandBusOccupied = util * clk / traceEnd * 100
|
||||
return ": {}".format(commandBusOccupied)
|
||||
|
||||
|
||||
@metric
|
||||
def average_response_latency_in_ns(connection):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("""SELECT AVG(RESP.PHASEBEGIN - REQ.PHASEBEGIN)/1000 FROM PHASES REQ, PHASES RESP
|
||||
WHERE REQ.PHASENAME = 'REQ' AND RESP.PHASENAME='RESP' AND REQ.TRANSACT = RESP.TRANSACT """)
|
||||
cursor.execute("""
|
||||
SELECT AVG(Resp.PhaseBegin - Req.PhaseBegin) / 1000
|
||||
FROM Phases Req, Phases Resp
|
||||
WHERE Req.PhaseName = 'REQ' AND Resp.PhaseName='RESP' AND Req.Transact = Resp.Transact
|
||||
""")
|
||||
result = cursor.fetchone()
|
||||
return round(result[0], 1)
|
||||
|
||||
|
||||
@metric
|
||||
def average_rd_response_latency_in_ns(connection):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("""
|
||||
SELECT
|
||||
AVG(RESP.PHASEBEGIN - REQ.PHASEBEGIN) / 1000
|
||||
FROM
|
||||
PHASES REQ,
|
||||
PHASES RESP
|
||||
INNER JOIN
|
||||
Transactions
|
||||
ON REQ.TRANSACT = Transactions.ID
|
||||
WHERE
|
||||
REQ.PHASENAME = 'REQ'
|
||||
AND RESP.PHASENAME = 'RESP'
|
||||
AND REQ.TRANSACT = RESP.TRANSACT
|
||||
AND Transactions.Command = "R"
|
||||
SELECT AVG(Resp.PhaseBegin - Req.PhaseBegin) / 1000
|
||||
FROM Phases Req, Phases Resp
|
||||
INNER JOIN Transactions
|
||||
ON Req.Transact = Transactions.ID
|
||||
WHERE Req.PhaseName = 'REQ' AND Resp.PhaseName = 'RESP'
|
||||
AND Req.Transact = Resp.Transact AND Transactions.Command = 'R'
|
||||
""")
|
||||
result = cursor.fetchone()
|
||||
return round(result[0], 1)
|
||||
|
||||
|
||||
@metric
|
||||
def average_wr_response_latency_in_ns(connection):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("""
|
||||
SELECT
|
||||
AVG(RESP.PHASEBEGIN - REQ.PHASEBEGIN) / 1000
|
||||
FROM
|
||||
PHASES REQ,
|
||||
PHASES RESP
|
||||
INNER JOIN
|
||||
Transactions
|
||||
ON REQ.TRANSACT = Transactions.ID
|
||||
WHERE
|
||||
REQ.PHASENAME = 'REQ'
|
||||
AND RESP.PHASENAME = 'RESP'
|
||||
AND REQ.TRANSACT = RESP.TRANSACT
|
||||
AND Transactions.Command = "W"
|
||||
SELECT AVG(Resp.PhaseBegin - Req.PhaseBegin) / 1000
|
||||
FROM Phases Req, Phases Resp
|
||||
INNER JOIN Transactions
|
||||
ON Req.Transact = Transactions.ID
|
||||
WHERE Req.PhaseName = 'REQ' AND Resp.PhaseName = 'RESP'
|
||||
AND Req.Transact = Resp.Transact AND Transactions.Command = 'W'
|
||||
""")
|
||||
result = cursor.fetchone()
|
||||
return round(result[0], 1)
|
||||
|
||||
|
||||
@metric
|
||||
def max_response_latency_in_ns(connection):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(""" SELECT max(RESP.PHASEBEGIN - REQ.PHASEBEGIN)/1000 FROM PHASES REQ, PHASES RESP
|
||||
WHERE REQ.PHASENAME = 'REQ' AND RESP.PHASENAME='RESP' AND REQ.TRANSACT = RESP.TRANSACT """)
|
||||
cursor.execute("""
|
||||
SELECT MAX(Resp.PhaseBegin - Req.PhaseBegin) / 1000
|
||||
FROM Phases Req, Phases Resp
|
||||
WHERE Req.PhaseName = 'REQ' AND Resp.PhaseName = 'RESP' AND Req.Transact = Resp.Transact
|
||||
""")
|
||||
result = cursor.fetchone()
|
||||
return result[0]
|
||||
|
||||
|
||||
@metric
|
||||
def max_rd_response_latency_in_ns(connection):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("""
|
||||
SELECT
|
||||
max(RESP.PHASEBEGIN - REQ.PHASEBEGIN) / 1000
|
||||
FROM
|
||||
PHASES REQ,
|
||||
PHASES RESP
|
||||
INNER JOIN
|
||||
Transactions
|
||||
ON REQ.TRANSACT = Transactions.ID
|
||||
WHERE
|
||||
REQ.PHASENAME = 'REQ'
|
||||
AND RESP.PHASENAME = 'RESP'
|
||||
AND REQ.TRANSACT = RESP.TRANSACT
|
||||
AND Transactions.Command = "R"
|
||||
SELECT MAX(Resp.PhaseBegin - Req.PhaseBegin) / 1000
|
||||
FROM Phases Req, Phases Resp
|
||||
INNER JOIN Transactions
|
||||
ON Req.Transact = Transactions.ID
|
||||
WHERE Req.PhaseName = 'REQ' AND Resp.PhaseName = 'RESP'
|
||||
AND Req.Transact = Resp.Transact AND Transactions.Command = 'R'
|
||||
""")
|
||||
result = cursor.fetchone()
|
||||
return round(result[0], 1)
|
||||
|
||||
|
||||
@metric
|
||||
def max_wr_response_latency_in_ns(connection):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("""
|
||||
SELECT
|
||||
max(RESP.PHASEBEGIN - REQ.PHASEBEGIN) / 1000
|
||||
FROM
|
||||
PHASES REQ,
|
||||
PHASES RESP
|
||||
INNER JOIN
|
||||
Transactions
|
||||
ON REQ.TRANSACT = Transactions.ID
|
||||
WHERE
|
||||
REQ.PHASENAME = 'REQ'
|
||||
AND RESP.PHASENAME = 'RESP'
|
||||
AND REQ.TRANSACT = RESP.TRANSACT
|
||||
AND Transactions.Command = "W"
|
||||
SELECT MAX(Resp.PhaseBegin - Req.PhaseBegin) / 1000
|
||||
FROM Phases Req, Phases Resp
|
||||
INNER JOIN Transactions
|
||||
ON Req.Transact = Transactions.ID
|
||||
WHERE Req.PhaseName = 'REQ' AND Resp.PhaseName = 'RESP'
|
||||
AND Req.Transact = Resp.Transact AND Transactions.Command = 'W'
|
||||
""")
|
||||
result = cursor.fetchone()
|
||||
return round(result[0], 1)
|
||||
|
||||
|
||||
@metric
|
||||
def trans_with_max_response_latency(connection):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(""" SELECT REQ.TRANSACT, max(RESP.PHASEBEGIN - REQ.PHASEBEGIN)/1000 FROM PHASES REQ, PHASES RESP
|
||||
WHERE REQ.PHASENAME = 'REQ' AND RESP.PHASENAME='RESP' AND REQ.TRANSACT = RESP.TRANSACT """)
|
||||
cursor.execute("""
|
||||
SELECT Req.Transact, MAX(Resp.PhaseBegin - Req.PhaseBegin) / 1000
|
||||
FROM Phases Req, Phases Resp
|
||||
WHERE Req.PhaseName = 'REQ' AND Resp.PhaseName = 'RESP' AND Req.Transact = Resp.Transact
|
||||
""")
|
||||
result = cursor.fetchone()
|
||||
return result[0]
|
||||
|
||||
|
||||
@metric
|
||||
def memory_active_in_clks(connection):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("""SELECT sum(DataStrobeEnd - DataStrobeBegin) FROM Transactions""")
|
||||
cursor.execute("SELECT SUM(DataStrobeEnd - DataStrobeBegin) FROM Phases")
|
||||
active = cursor.fetchone()[0]
|
||||
if getPseudoChannelMode(connection):
|
||||
active /= 2
|
||||
clk, _ = getClock(connection)
|
||||
return (active / clk)
|
||||
return active / clk
|
||||
|
||||
|
||||
@metric
|
||||
def memory_total_in_clks(connection):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(""" SELECT max(DataStrobeEnd) FROM Transactions """)
|
||||
cursor.execute("SELECT MAX(DataStrobeEnd) FROM Phases")
|
||||
total = cursor.fetchone()
|
||||
clk, _ = getClock(connection)
|
||||
return (total[0]/clk)
|
||||
return total[0] / clk
|
||||
|
||||
|
||||
@metric
|
||||
def memory_idle_in_clks(connection):
|
||||
# This complex query identifies idle times where the DRAM is not used.
|
||||
# This complex query identifies idle times when the DRAM is not used.
|
||||
# The code works also if schedulers are used.
|
||||
|
||||
cursor = connection.cursor()
|
||||
|
||||
# Create a table with transactions sorted by BeginRequest:
|
||||
# (RowNum, BeginRequest)
|
||||
query = """ DROP TABLE IF EXISTS transactionsInRequestOrder; """
|
||||
query = """DROP TABLE IF EXISTS transactionsInRequestOrder;"""
|
||||
cursor.execute(query)
|
||||
|
||||
query = """
|
||||
@@ -229,50 +220,50 @@ def memory_idle_in_clks(connection):
|
||||
FROM
|
||||
Phases p
|
||||
WHERE
|
||||
p.PhaseName = "REQ";
|
||||
p.PhaseName = 'REQ';
|
||||
"""
|
||||
cursor.execute(query)
|
||||
|
||||
# Create a table with transactions sorted by BeginResponse:
|
||||
# (RowNum, ID, EndResponse)
|
||||
query = """ DROP TABLE IF EXISTS transactionsInResponseOrder; """
|
||||
query = """DROP TABLE IF EXISTS transactionsInResponseOrder;"""
|
||||
cursor.execute(query)
|
||||
|
||||
query = """
|
||||
CREATE TEMPORARY TABLE transactionsInResponseOrder AS
|
||||
SELECT
|
||||
ROW_NUMBER () OVER (ORDER BY q.PhaseBegin) RowNum,
|
||||
q.Transact AS ID,
|
||||
q.PhaseEnd AS EndResponse
|
||||
q.PhaseEnd AS EndResponse
|
||||
FROM
|
||||
Phases q
|
||||
WHERE
|
||||
q.PhaseName = "RESP";
|
||||
q.PhaseName = 'RESP';
|
||||
"""
|
||||
cursor.execute(query)
|
||||
|
||||
# Sum up the idle times:
|
||||
query = """
|
||||
SELECT
|
||||
sum(c.BeginRequest - b.EndResponse) AS idle
|
||||
SUM(c.BeginRequest - b.EndResponse) AS idle
|
||||
FROM
|
||||
transactionsInRequestOrder AS a, transactionsInResponseOrder AS b, transactionsInRequestOrder AS c
|
||||
WHERE
|
||||
a.RowNum=b.RowNum AND
|
||||
c.RowNum=(a.RowNum+1) AND
|
||||
c.BeginRequest>b.EndResponse;
|
||||
a.RowNum = b.RowNum AND
|
||||
c.RowNum = (a.RowNum + 1) AND
|
||||
c.BeginRequest > b.EndResponse;
|
||||
"""
|
||||
cursor.execute(query)
|
||||
idle = cursor.fetchone()
|
||||
|
||||
cursor.execute(""" SELECT min(PhaseBegin) FROM Phases WHERE PhaseName = 'REQ' """)
|
||||
cursor.execute("""SELECT MIN(PhaseBegin) FROM Phases WHERE PhaseName = 'REQ'""")
|
||||
idle_start = cursor.fetchone()
|
||||
clk, unit = getClock(connection)
|
||||
|
||||
if (idle[0] is None):
|
||||
return (idle_start[0] / clk)
|
||||
if idle[0] is None:
|
||||
return idle_start[0] / clk
|
||||
else:
|
||||
return ((idle[0] + idle_start[0]) / clk)
|
||||
return (idle[0] + idle_start[0]) / clk
|
||||
|
||||
|
||||
@metric
|
||||
def memory_delayed_in_clks(connection):
|
||||
@@ -281,71 +272,69 @@ def memory_delayed_in_clks(connection):
|
||||
idle = memory_idle_in_clks(connection)
|
||||
return total - active - idle
|
||||
|
||||
|
||||
@metric
|
||||
def delayed_reasons(connection):
|
||||
cursor = connection.cursor()
|
||||
|
||||
# Create a table with sorted Datastrobes:
|
||||
# Create a table with sorted data strobes:
|
||||
# (RowNum, ID, Begin, End)
|
||||
query = """ DROP TABLE IF EXISTS dataStrobesInOrder; """
|
||||
cursor.execute(query)
|
||||
cursor.execute("DROP TABLE IF EXISTS dataStrobesInOrder;")
|
||||
|
||||
query = """
|
||||
cursor.execute("""
|
||||
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,
|
||||
t.TRow as Row,
|
||||
t.TBank as Bank,
|
||||
t.Command as Command
|
||||
ROW_NUMBER () OVER (ORDER BY DataStrobeBegin) RowNum,
|
||||
Transact AS ID,
|
||||
DataStrobeBegin AS Begin,
|
||||
DataStrobeEnd AS End,
|
||||
Row,
|
||||
Bank,
|
||||
PhaseName AS Command
|
||||
FROM
|
||||
Transactions t
|
||||
Phases
|
||||
WHERE
|
||||
t.DataStrobeBegin <> 0 AND
|
||||
t.DataStrobeEnd <> 0;
|
||||
"""
|
||||
cursor.execute(query)
|
||||
DataStrobeBegin <> 0 AND
|
||||
DataStrobeEnd <> 0;
|
||||
""")
|
||||
|
||||
# Create a table with transactions sorted by BeginRequest:
|
||||
# (RowNum, BeginRequest)
|
||||
query = """ DROP TABLE IF EXISTS transactionsInRequestOrder; """
|
||||
cursor.execute(query)
|
||||
cursor.execute("""DROP TABLE IF EXISTS transactionsInRequestOrder;""")
|
||||
|
||||
query = """
|
||||
CREATE TEMPORARY TABLE transactionsInRequestOrder AS
|
||||
SELECT
|
||||
ROW_NUMBER () OVER (ORDER BY p.PhaseBegin) RowNum,
|
||||
p.PhaseBegin AS BeginRequest
|
||||
ROW_NUMBER () OVER (ORDER BY PhaseBegin) RowNum,
|
||||
PhaseBegin AS BeginRequest
|
||||
FROM
|
||||
Phases p
|
||||
Phases
|
||||
WHERE
|
||||
p.PhaseName = "REQ";
|
||||
PhaseName = 'REQ';
|
||||
"""
|
||||
cursor.execute(query)
|
||||
|
||||
# Create a table with transactions sorted by BeginResponse:
|
||||
# (RowNum, ID, EndResponse)
|
||||
query = """ DROP TABLE IF EXISTS transactionsInResponseOrder; """
|
||||
query = """DROP TABLE IF EXISTS transactionsInResponseOrder;"""
|
||||
cursor.execute(query)
|
||||
|
||||
query = """
|
||||
CREATE TEMPORARY TABLE transactionsInResponseOrder AS
|
||||
SELECT
|
||||
ROW_NUMBER () OVER (ORDER BY q.PhaseBegin) RowNum,
|
||||
q.Transact AS ID,
|
||||
q.PhaseEnd AS EndResponse
|
||||
ROW_NUMBER () OVER (ORDER BY PhaseBegin) RowNum,
|
||||
Transact AS ID,
|
||||
PhaseEnd AS EndResponse
|
||||
FROM
|
||||
Phases q
|
||||
Phases
|
||||
WHERE
|
||||
q.PhaseName = "RESP";
|
||||
PhaseName = 'RESP';
|
||||
"""
|
||||
cursor.execute(query)
|
||||
|
||||
# Create a table with transaction IDs that start a idle time:
|
||||
# Create a table with transaction IDs that start an idle time:
|
||||
# (ID)
|
||||
query = """ DROP TABLE IF EXISTS idleGaps; """
|
||||
query = """DROP TABLE IF EXISTS idleGaps;"""
|
||||
cursor.execute(query)
|
||||
|
||||
query = """
|
||||
@@ -355,15 +344,15 @@ def delayed_reasons(connection):
|
||||
FROM
|
||||
transactionsInRequestOrder AS a, transactionsInResponseOrder AS b, transactionsInRequestOrder AS c
|
||||
WHERE
|
||||
a.RowNum=b.RowNum AND
|
||||
c.RowNum=(a.RowNum+1) AND
|
||||
c.BeginRequest>b.EndResponse;
|
||||
a.RowNum = b.RowNum AND
|
||||
c.RowNum = (a.RowNum + 1) AND
|
||||
c.BeginRequest > b.EndResponse;
|
||||
"""
|
||||
cursor.execute(query)
|
||||
|
||||
# Create a table which features IDs that form gaps on the databus:
|
||||
# Create a table which features IDs that form gaps on the data bus:
|
||||
# (gapBeginID, gapEndID)
|
||||
query = """ DROP TABLE IF EXISTS delayedDataBusGaps; """
|
||||
query = """DROP TABLE IF EXISTS delayedDataBusGaps;"""
|
||||
cursor.execute(query)
|
||||
|
||||
query = """
|
||||
@@ -377,9 +366,9 @@ def delayed_reasons(connection):
|
||||
dataStrobesInOrder a,
|
||||
dataStrobesInOrder b
|
||||
WHERE
|
||||
(a.RowNum) = (b.RowNum-1) AND
|
||||
a.RowNum = b.RowNum - 1 AND
|
||||
b.Begin > a.End AND
|
||||
a.ID not in (SELECT ID FROM idleGaps);
|
||||
a.ID NOT IN (SELECT ID FROM idleGaps);
|
||||
"""
|
||||
cursor.execute(query)
|
||||
|
||||
@@ -389,8 +378,8 @@ def delayed_reasons(connection):
|
||||
COUNT(*)
|
||||
FROM delayedDataBusGaps
|
||||
WHERE
|
||||
gapBeginCommand = "R" AND
|
||||
gapEndCommand = "W";
|
||||
(gapBeginCommand = 'RD' OR gapBeginCommand = 'RDA') AND
|
||||
(gapEndCommand = 'WR' OR gapEndCommand = 'WRA');
|
||||
"""
|
||||
cursor.execute(query)
|
||||
RW = cursor.fetchone()[0]
|
||||
@@ -402,8 +391,8 @@ def delayed_reasons(connection):
|
||||
FROM
|
||||
delayedDataBusGaps
|
||||
WHERE
|
||||
gapBeginCommand = "W" AND
|
||||
gapEndCommand = "R";
|
||||
(gapBeginCommand = 'WR' OR gapBeginCommand = 'WRA') AND
|
||||
(gapEndCommand = 'RD' OR gapEndCommand = 'RDA');
|
||||
"""
|
||||
cursor.execute(query)
|
||||
WR = cursor.fetchone()[0]
|
||||
@@ -417,10 +406,10 @@ def delayed_reasons(connection):
|
||||
FROM
|
||||
delayedDataBusGaps d, Phases p
|
||||
WHERE
|
||||
d.gapBeginCommand = "R" AND
|
||||
d.gapEndCommand = "R" AND
|
||||
(d.gapBeginCommand = 'RD' OR d.gapBeginCommand = 'RDA') AND
|
||||
(d.gapEndCommand = 'RD' OR d.gapEndCommand = 'RDA') AND
|
||||
p.Transact = d.gapEndID AND
|
||||
p.PhaseName = "ACT"
|
||||
p.PhaseName = 'ACT'
|
||||
GROUP BY
|
||||
d.gapBeginID
|
||||
)
|
||||
@@ -437,10 +426,10 @@ def delayed_reasons(connection):
|
||||
FROM
|
||||
delayedDataBusGaps d, Phases p
|
||||
WHERE
|
||||
d.gapBeginCommand = "W" AND
|
||||
d.gapEndCommand = "W" AND
|
||||
(d.gapBeginCommand = 'WR' OR d.gapBeginCommand = 'WRA') AND
|
||||
(d.gapEndCommand = 'WR' OR d.gapEndCommand = 'WRA') AND
|
||||
p.Transact = d.gapEndID AND
|
||||
p.PhaseName = "ACT"
|
||||
p.PhaseName = 'ACT'
|
||||
GROUP BY
|
||||
d.gapBeginID
|
||||
)
|
||||
@@ -468,27 +457,33 @@ def delayed_reasons(connection):
|
||||
result = "RW: {}, WR: {}, RRM: {}, WWM: {}, Other: {}".format(RW, WR, RRM, WWM, other)
|
||||
return result
|
||||
|
||||
|
||||
@metric
|
||||
def memory_idle_in_percent(connection):
|
||||
total = memory_total_in_clks(connection)
|
||||
idle = memory_idle_in_clks(connection)
|
||||
return (idle/total)*100
|
||||
|
||||
|
||||
@metric
|
||||
def memory_active_in_percent(connection):
|
||||
total = memory_total_in_clks(connection)
|
||||
active = memory_active_in_clks(connection)
|
||||
return (active/total)*100
|
||||
|
||||
|
||||
@metric
|
||||
def memory_delayed_in_percent(connection):
|
||||
total = memory_total_in_clks(connection)
|
||||
delayed = memory_delayed_in_clks(connection)
|
||||
return (delayed/total)*100
|
||||
|
||||
|
||||
@metric
|
||||
def memory_idle_active_delayed_check(connection):
|
||||
return memory_idle_in_percent(connection) + memory_active_in_percent(connection) + memory_delayed_in_percent(connection)
|
||||
return memory_idle_in_percent(connection) + memory_active_in_percent(connection) \
|
||||
+ memory_delayed_in_percent(connection)
|
||||
|
||||
|
||||
@metric
|
||||
def memory_utilisation_percent_without_idle(connection):
|
||||
@@ -497,72 +492,77 @@ def memory_utilisation_percent_without_idle(connection):
|
||||
idle = memory_idle_in_clks(connection)
|
||||
return (active/(total-idle))*100
|
||||
|
||||
|
||||
@metric
|
||||
def memory_utilisation_in_Gibps_without_idle(connection):
|
||||
# This function calculates the memory utilisation in Gibit/s considering the memory_utilisation_percent_new function result.
|
||||
# This function calculates the memory utilisation in Gibit/s considering
|
||||
# the memory_utilisation_percent_new function result.
|
||||
maxDataRate = maximum_data_rate(connection)
|
||||
memoryPercent = memory_utilisation_percent_without_idle(connection)
|
||||
return (memoryPercent/100)*(maxDataRate/1024)
|
||||
|
||||
|
||||
@metric
|
||||
def memory_utilisation_percent_including_idle(connection):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(""" SELECT sum(DataStrobeEnd - DataStrobeBegin) FROM transactions """)
|
||||
cursor.execute("""SELECT SUM(DataStrobeEnd - DataStrobeBegin) FROM Phases""")
|
||||
active = cursor.fetchone()
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(""" SELECT max(DataStrobeEnd) FROM Transactions """)
|
||||
cursor.execute("""SELECT MAX(DataStrobeEnd) FROM Phases""")
|
||||
total = cursor.fetchone()
|
||||
return (active[0]/total[0])*100
|
||||
return (active[0] / total[0]) * 100
|
||||
|
||||
def refreshMissDecision(connection, calculatedMetrics):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("""SELECT phases.ID,PhaseBegin,PhaseEnd,TBank FROM Phases INNER JOIN transactions
|
||||
on transactions.id = phases.transact WHERE PhaseName IN ('REFAB')' """)
|
||||
queryMinREQ = """SELECT id,min(PhaseBegin) FROM (SELECT transactions.id, PhaseBegin FROM transactions
|
||||
inner join ranges on ranges.id = transactions.range inner join phases on phases.transact = transactions.id
|
||||
where tthread != 0 and tbank = :bank and PhaseName = "REQ" and ranges.begin<:begin and ranges.end>:end)"""
|
||||
|
||||
queryMinRESP = """SELECT id,min(PhaseBegin) FROM (SELECT transactions.id, PhaseBegin FROM transactions
|
||||
inner join ranges on ranges.id = transactions.range inner join phases on phases.transact = transactions.id
|
||||
where tthread != 0 and tbank = :bank and PhaseName = "RESP" and ranges.begin<:begin and ranges.end>:end) """
|
||||
|
||||
missDecisions = 0
|
||||
totalDecisios = 0
|
||||
|
||||
for refresh in cursor:
|
||||
id = refresh[0]
|
||||
begin = refresh[1]
|
||||
end = refresh[2]
|
||||
bank = refresh[3]
|
||||
# print('Refresh: {0} {1} {2} {3}'.format(id,begin,end,bank))
|
||||
|
||||
cursorMinREQ = connection.cursor()
|
||||
cursorMinRESP = connection.cursor()
|
||||
|
||||
cursorMinREQ.execute(queryMinREQ, {"bank": bank, "begin": begin, "end": end})
|
||||
cursorMinRESP.execute(queryMinRESP, {"bank": bank, "begin": begin, "end": end})
|
||||
|
||||
earliestReq = cursorMinREQ.fetchone()
|
||||
earliestResp = cursorMinRESP.fetchone()
|
||||
if (earliestReq[0] is not None):
|
||||
totalDecisios = totalDecisios + 1
|
||||
if(earliestReq[0] != earliestResp[0]):
|
||||
missDecisions = missDecisions + 1
|
||||
# print("earliest Req: {0}| earliest Res: {1}".format(earliestReq[0], earliestResp[0]))
|
||||
|
||||
if (totalDecisios != 0):
|
||||
# calculatedMetrics.append(("Total Missdecisions", missDecisions))
|
||||
calculatedMetrics.append(("Relative Missdecisions", 1.0*missDecisions/totalDecisios))
|
||||
else:
|
||||
calculatedMetrics.append(("Total Missdecisions", 0))
|
||||
calculatedMetrics.append(("Relative Missdecisions", 0))
|
||||
# def refreshMissDecision(connection, calculatedMetrics):
|
||||
# cursor = connection.cursor()
|
||||
# cursor.execute("""SELECT Phases.ID, PhaseBegin, PhaseEnd, TBank FROM Phases INNER JOIN Transactions
|
||||
# ON Transactions.ID = Phases.Transact WHERE PhaseName IN ('REFAB')' """)
|
||||
# queryMinREQ = """SELECT ID, MIN(PhaseBegin) FROM (SELECT Transactions.ID, PhaseBegin FROM Transactions
|
||||
# INNER JOIN ranges ON ranges.id = Transactions.Range INNER JOIN Phases ON Phases.Transact = Transactions.ID
|
||||
# WHERE TThread != 0 AND TBank = :bank and PhaseName = "REQ" and ranges.begin < :begin AND ranges.end > :end)"""
|
||||
#
|
||||
# queryMinRESP = """SELECT ID, MIN(PhaseBegin) FROM (SELECT Transactions.ID, PhaseBegin FROM Transactions
|
||||
# INNER JOIN ranges ON ranges.id = Transactions.Range INNER JOIN Phases ON Phases.Transact = Transactions.ID
|
||||
# WHERE TThread != 0 AND TBank = :bank AND PhaseName = "RESP" AND ranges.begin < :begin AND ranges.end > :end) """
|
||||
#
|
||||
# missDecisions = 0
|
||||
# totalDecisions = 0
|
||||
#
|
||||
# for refresh in cursor:
|
||||
# id = refresh[0]
|
||||
# begin = refresh[1]
|
||||
# end = refresh[2]
|
||||
# bank = refresh[3]
|
||||
# # print('Refresh: {0} {1} {2} {3}'.format(id,begin,end,bank))
|
||||
#
|
||||
# cursorMinREQ = connection.cursor()
|
||||
# cursorMinRESP = connection.cursor()
|
||||
#
|
||||
# cursorMinREQ.execute(queryMinREQ, {"bank": bank, "begin": begin, "end": end})
|
||||
# cursorMinRESP.execute(queryMinRESP, {"bank": bank, "begin": begin, "end": end})
|
||||
#
|
||||
# earliestReq = cursorMinREQ.fetchone()
|
||||
# earliestResp = cursorMinRESP.fetchone()
|
||||
# if earliestReq[0] is not None:
|
||||
# totalDecisions = totalDecisions + 1
|
||||
# if earliestReq[0] != earliestResp[0]:
|
||||
# missDecisions = missDecisions + 1
|
||||
# # print("earliest Req: {0}| earliest Res: {1}".format(earliestReq[0], earliestResp[0]))
|
||||
#
|
||||
# if totalDecisions != 0:
|
||||
# # calculatedMetrics.append(("Total Missdecisions", missDecisions))
|
||||
# calculatedMetrics.append(("Relative Missdecisions", 1.0*missDecisions/totalDecisions))
|
||||
# else:
|
||||
# calculatedMetrics.append(("Total Missdecisions", 0))
|
||||
# calculatedMetrics.append(("Relative Missdecisions", 0))
|
||||
|
||||
|
||||
@threadMetric
|
||||
def average_response_latency_in_ns(connection, thread):
|
||||
cursor = connection.cursor()
|
||||
query = """SELECT avg(PhaseBegin-timeOfGeneration)/1000 FROM transactions INNER JOIN Phases
|
||||
ON phases.transact = transactions.ID WHERE PhaseName='RESP' AND TThread = :Thread """
|
||||
query = """SELECT AVG(Resp.PhaseBegin - Req.PhaseBegin) / 1000 FROM Phases Req, Phases Resp INNER JOIN Transactions
|
||||
ON Req.Transact = Transactions.ID WHERE Req.Transact = Resp.Transact AND Req.PhaseName = 'REQ'
|
||||
AND Resp.PhaseName = 'RESP' AND Thread = :thread"""
|
||||
|
||||
cursor.execute(query, {"Thread": thread})
|
||||
result = cursor.fetchone()
|
||||
@@ -572,7 +572,7 @@ def average_response_latency_in_ns(connection, thread):
|
||||
def addStallTime(times, begin, end):
|
||||
time = begin
|
||||
while time <= end:
|
||||
if(time in times):
|
||||
if time in times:
|
||||
times[time] = times[time] + 1
|
||||
else:
|
||||
times[time] = 1
|
||||
@@ -580,12 +580,12 @@ def addStallTime(times, begin, end):
|
||||
|
||||
|
||||
# @threadMetric
|
||||
def paralellism(connection, thread):
|
||||
def parallelism(connection, thread):
|
||||
cursor = connection.cursor()
|
||||
stalltimes = {}
|
||||
query = """SELECT transactions.ID,MIN(phaseBegin)/:clk,MAX(phaseEnd)/:clk
|
||||
from phases inner join transactions on phases.transact=transactions.id
|
||||
where phaseName Not in ('REQ','RESP') and tthread=:Thread group by transactions.ID """
|
||||
query = """SELECT Transactions.ID, MIN(PhaseBegin) / :clk, MAX(PhaseEnd) / :clk
|
||||
FROM Phases INNER JOIN Transactions ON Phases.Transact = Transactions.ID
|
||||
WHERE PhaseName NOT IN ('REQ','RESP') AND Thread = :thread GROUP BY Transactions.ID """
|
||||
|
||||
clk, unit = getClock(connection)
|
||||
cursor.execute(query, {"Thread": thread, "clk": clk})
|
||||
@@ -600,7 +600,9 @@ def paralellism(connection, thread):
|
||||
@threadMetric
|
||||
def thread_conclusion_in_ns(connection, thread):
|
||||
cursor = connection.cursor()
|
||||
query = """ SELECT max(PhaseEnd)/1000 FROM Phases INNER JOIN Transactions on Phases.transact=Transactions.id WHERE TThread = :Thread """
|
||||
query = """
|
||||
SELECT max(PhaseEnd) / 1000 FROM Phases INNER JOIN Transactions
|
||||
ON Phases.Transact = Transactions.ID WHERE Thread = :thread """
|
||||
cursor.execute(query, {"Thread": thread})
|
||||
result = cursor.fetchone()
|
||||
return result[0]
|
||||
@@ -738,98 +740,81 @@ def SREFB_count(connection):
|
||||
|
||||
@metric
|
||||
def number_of_accesses(connection):
|
||||
return REQ_count(connection)
|
||||
return RD_count(connection) + RDA_count(connection) + WR_count(connection) + WRA_count(connection)
|
||||
|
||||
|
||||
@metric
|
||||
def accesses_per_activate(connection):
|
||||
return round(float(REQ_count(connection)) / ACT_count(connection), 1)
|
||||
return round(float(number_of_accesses(connection)) / ACT_count(connection), 1)
|
||||
|
||||
|
||||
@metric
|
||||
def bank_overlap_ratio(connection):
|
||||
# Calculates how many banks are open in parallel
|
||||
clk, unit = getClock(connection)
|
||||
numberOfRanks = getNumberOfRanks(connection)
|
||||
numberOfBankGroups = getNumberOfBankGroups(connection)
|
||||
numberOfBanks = getNumberOfBanks(connection)
|
||||
per2BankOffset = getPer2BankOffset(connection)
|
||||
banksPerRank = int(numberOfBanks / numberOfRanks)
|
||||
banksPerGroup = int(numberOfBanks / numberOfBankGroups)
|
||||
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("select TraceEnd from GeneralInfo")
|
||||
cursor.execute("SELECT TraceEnd FROM GeneralInfo")
|
||||
traceEndTMP = cursor.fetchone()
|
||||
traceEnd = int(traceEndTMP[0]/clk)
|
||||
traceEnd = int(traceEndTMP[0] / clk)
|
||||
trace = []
|
||||
|
||||
cursor.execute("""
|
||||
select p1.PhaseBegin, p1.PhaseName from Phases p1
|
||||
where
|
||||
(p1.PhaseName = "ACT" or p1.PhaseName = "PREPB" or p1.PhaseName = "PRE" or p1.PhaseName = "PRESB"
|
||||
or p1.PhaseName = "PREAB" or p1.PhaseName = "PREA" or p1.PhaseName = "RDA" or p1.PhaseName = "WRA")
|
||||
order by PhaseBegin
|
||||
SELECT PhaseBegin, PhaseName, Rank, BankGroup, Bank
|
||||
FROM Phases
|
||||
WHERE (PhaseName = 'ACT' OR PhaseName = 'PREPB' OR PhaseName = 'PREP2B' OR PhaseName = 'PRESB'
|
||||
OR PhaseName = 'PREAB' OR PhaseName = 'RDA' OR PhaseName = 'WRA')
|
||||
ORDER BY PhaseBegin
|
||||
""")
|
||||
prevPhase = "PREAB"
|
||||
prevTime = 0
|
||||
|
||||
# prevPhase = "PREAB"
|
||||
# prevTime = 0
|
||||
|
||||
# clk of command, name, rank, bank group, bank
|
||||
for c in cursor:
|
||||
trace.append([(int(c[0]/clk)), c[1]])
|
||||
trace.append([(int(c[0] / clk)), c[1], c[2], c[3], c[4]])
|
||||
|
||||
# Insert a pseudo precharge all to mark the end of the trace
|
||||
trace.append([traceEnd, "PREAB"])
|
||||
# Insert a pseudo precharge all to mark the end of the trace on all ranks
|
||||
for i in range(numberOfRanks):
|
||||
trace.append([traceEnd, "PREAB", i, 0, 0])
|
||||
|
||||
bankCounter = 0
|
||||
bankTime = []
|
||||
|
||||
for i in range(0, getNumberOfBanks(connection)+1):
|
||||
bankTime.append(0)
|
||||
bankCounter = [False] * numberOfBanks
|
||||
|
||||
# + 1 because we have #banks + 1 active states (0 to all banks active)
|
||||
bankTime = [0.0] * (numberOfBanks + 1)
|
||||
currentTime = 0
|
||||
validBankRange = range(0, getNumberOfBanks(connection) + 1)
|
||||
|
||||
# RGR uses ACTB and PREB for refresh
|
||||
actbCnt = 0
|
||||
for t in trace:
|
||||
|
||||
interval = t[0] - currentTime
|
||||
bankTime[bankCounter] += interval
|
||||
bankTime[sum(bankCounter)] += interval
|
||||
currentTime = t[0]
|
||||
|
||||
if(t[1] == "ACT"):
|
||||
bankCounter += 1
|
||||
if not (bankCounter in validBankRange):
|
||||
print("Unexpected ACT. bankCounter was {0} valid range is python range {1}".format(bankCounter, validBankRange))
|
||||
elif t[1] == "ACTB":
|
||||
actbCnt += 1
|
||||
elif(t[1] == "PREAB" or t[1] == "PREA"):
|
||||
bankCounter = 0
|
||||
elif(t[1] == "PREPB" or t[1] == "PRE"):
|
||||
if (bankCounter > 0):
|
||||
bankCounter -= 1
|
||||
else:
|
||||
print("Unexpected PREPB. bankCounter was {0} valid range is python range {1}".format(bankCounter, validBankRange))
|
||||
elif(t[1] == "PREB"):
|
||||
# RGR first PREB closes the row ACT follows, then PREB again.
|
||||
if actbCnt > 0:
|
||||
# Ignore the second PREB
|
||||
actbCnt -= 1
|
||||
else:
|
||||
# Treat the first PREB which closes the row
|
||||
if bankCounter > 0:
|
||||
bankCounter -= 1
|
||||
else:
|
||||
print("Unexpected PREB. bankCounter was {0} valid range is python range {1}".format(bankCounter, validBankRange))
|
||||
elif(t[1] == "WRA"):
|
||||
if (bankCounter > 0):
|
||||
bankCounter -= 1
|
||||
else:
|
||||
print("Unexpected WRA. bankCounter was {0} valid range is python range {1}".format(bankCounter, validBankRange))
|
||||
elif(t[1] == "RDA"):
|
||||
if (bankCounter > 0):
|
||||
bankCounter -= 1
|
||||
else:
|
||||
print("Unexpected RDA. bankCounter was {0} valid range is python range {1}".format(bankCounter, validBankRange))
|
||||
if t[1] == "ACT":
|
||||
bankCounter[t[4]] = True
|
||||
elif t[1] in ["PREPB", "RDA", "WRA"]:
|
||||
bankCounter[t[4]] = False
|
||||
elif t[1] == "PREP2B":
|
||||
bankCounter[t[4]] = False
|
||||
bankCounter[t[4] + per2BankOffset] = False
|
||||
elif t[1] == "PRESB":
|
||||
for i in range(t[4], t[4] + banksPerRank, banksPerGroup):
|
||||
bankCounter[i] = False
|
||||
elif t[1] == "PREAB":
|
||||
for i in range(t[2] * banksPerRank, (t[2] + 1) * banksPerRank):
|
||||
bankCounter[i] = False
|
||||
else:
|
||||
print("ERROR")
|
||||
return 0
|
||||
|
||||
for i in range(0, getNumberOfBanks(connection)+1):
|
||||
bankTime[i] = round(bankTime[i]/traceEnd * 100, 2)
|
||||
for i in range(numberOfBanks + 1):
|
||||
bankTime[i] = round(bankTime[i] / traceEnd * 100, 2)
|
||||
|
||||
return ",".join(format(x, "6.2f") for x in bankTime)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user