diff --git a/DRAMSys/traceAnalyzer/scripts/metrics.py b/DRAMSys/traceAnalyzer/scripts/metrics.py index d3ba866b..03f7d186 100644 --- a/DRAMSys/traceAnalyzer/scripts/metrics.py +++ b/DRAMSys/traceAnalyzer/scripts/metrics.py @@ -79,50 +79,66 @@ def memory_total(connection): def memory_idle(connection): # This complex query identifies idle times where 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; """ + cursor.execute(query) + query = """ - DROP TABLE IF EXISTS phasesInOrder; + CREATE TEMPORARY TABLE transactionsInRequestOrder AS + SELECT + ROW_NUMBER () OVER (ORDER BY p.PhaseBegin) RowNum, + p.PhaseBegin AS BeginRequest + FROM + Phases p + WHERE + p.PhaseName = "REQ"; """ cursor.execute(query) - + + # Create a table with transactions sorted by BeginResponse: + # (RowNum, ID, EndResponse) + query = """ DROP TABLE IF EXISTS transactionsInResponseOrder; """ + cursor.execute(query) + query = """ - -- The temporary table selects all TLM phases and sorts them according to BEGIN_RESP - CREATE TEMPORARY TABLE phasesInOrder AS + CREATE TEMPORARY TABLE transactionsInResponseOrder AS SELECT ROW_NUMBER () OVER (ORDER BY q.PhaseBegin) RowNum, - p.PhaseBegin AS BeginRequest, - p.PhaseEnd AS EndRequest, - q.PhaseBegin AS BeginResponse, + q.Transact AS ID, q.PhaseEnd AS EndResponse FROM - Phases p, Phases q WHERE - p.PhaseName = "REQ" AND - q.PhaseName = "RESP" AND - p.Transact = q.Transact; + q.PhaseName = "RESP"; """ cursor.execute(query) + # Sum up the idle times: query = """ - SELECT - sum(b.BeginRequest - a.EndResponse) AS idle - FROM - phasesInOrder AS a, phasesInOrder AS b + SELECT + sum(c.BeginRequest - b.EndResponse) AS idle + FROM + transactionsInRequestOrder AS a, transactionsInResponseOrder AS b, transactionsInRequestOrder AS c WHERE - (a.RowNum)=(b.RowNum-1) AND -- In the list of ordered transactions always compare two adjacent - b.BeginRequest > a.EndResponse; -- This makes sure that no negative summands exists + a.RowNum=b.RowNum AND + c.RowNum=(a.RowNum+1) AND + c.BeginRequest>b.EndResponse; """ - cursor.execute(query) - + cursor.execute(query) idle = cursor.fetchone() + + cursor.execute(""" SELECT min(PhaseBegin) FROM Phases WHERE PhaseName = 'REQ' """) + idle_start = cursor.fetchone() + clk, unit = getClock(connection) + if (idle[0] is None): - return 0 + return (idle_start[0] / clk) else: - clk, unit = getClock(connection) - return (idle[0]/clk) + return ((idle[0] + idle_start[0]) / clk) @metric def memory_delayed(connection): @@ -141,48 +157,58 @@ def delayed_reasons(connection): 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, - t.TRow as Row, - t.TBank as Bank, - t.Command as Command - - FROM - Transactions t - WHERE - t.DataStrobeBegin <> 0 AND - t.DataStrobeEnd <> 0; + 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 + 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; """ + + # Create a table with transactions sorted by BeginRequest: + # (RowNum, BeginRequest) + query = """ DROP TABLE IF EXISTS transactionsInRequestOrder; """ cursor.execute(query) - + query = """ - CREATE TEMPORARY TABLE phasesInOrder AS - SELECT - ROW_NUMBER () OVER (ORDER BY q.PhaseBegin) RowNum, - p.Transact AS ID, - p.PhaseBegin AS BeginRequest, - p.PhaseEnd AS EndRequest, - q.PhaseBegin AS BeginResponse, - q.PhaseEnd AS EndResponse - FROM - Phases p, - Phases q - WHERE - p.PhaseName = "REQ" - AND q.PhaseName = "RESP" - AND p.Transact = q.Transact; + CREATE TEMPORARY TABLE transactionsInRequestOrder AS + SELECT + ROW_NUMBER () OVER (ORDER BY p.PhaseBegin) RowNum, + p.PhaseBegin AS BeginRequest + FROM + Phases p + WHERE + p.PhaseName = "REQ"; """ cursor.execute(query) - + + # Create a table with transactions sorted by BeginResponse: + # (RowNum, ID, EndResponse) + 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 + FROM + Phases q + WHERE + q.PhaseName = "RESP"; + """ + cursor.execute(query) + # Create a table with transaction IDs that start a idle time: # (ID) query = """ DROP TABLE IF EXISTS idleGaps; """ @@ -190,11 +216,14 @@ def delayed_reasons(connection): query = """ CREATE TEMPORARY TABLE idleGaps AS - SELECT a.ID AS ID - FROM phasesInOrder AS a, phasesInOrder AS b + SELECT + b.ID AS ID + FROM + transactionsInRequestOrder AS a, transactionsInResponseOrder AS b, transactionsInRequestOrder AS c WHERE - (a.RowNum)=(b.RowNum-1) AND - b.BeginRequest > a.EndResponse; + a.RowNum=b.RowNum AND + c.RowNum=(a.RowNum+1) AND + c.BeginRequest>b.EndResponse; """ cursor.execute(query) @@ -204,7 +233,7 @@ def delayed_reasons(connection): cursor.execute(query) query = """ - CREATE TEMPORARY TABLE delayedDataBusGaps AS + CREATE TEMPORARY TABLE delayedDataBusGaps AS SELECT a.ID AS gapBeginID, b.ID AS gapEndID, @@ -236,7 +265,8 @@ def delayed_reasons(connection): query = """ SELECT COUNT(*) - FROM delayedDataBusGaps + FROM + delayedDataBusGaps WHERE gapBeginCommand = "W" AND gapEndCommand = "R"; @@ -246,28 +276,40 @@ def delayed_reasons(connection): # Count RR Miss query = """ - SELECT - COUNT(*) - FROM delayedDataBusGaps d, Phases p - WHERE - d.gapBeginCommand = "R" AND - d.gapEndCommand = "R" AND - p.Transact = d.gapEndID AND - PhaseName = "ACT"; + SELECT COUNT(*) FROM + ( + SELECT + COUNT(*) + FROM + delayedDataBusGaps d, Phases p + WHERE + d.gapBeginCommand = "R" AND + d.gapEndCommand = "R" AND + p.Transact = d.gapEndID AND + p.PhaseName = "ACT" + GROUP BY + d.gapBeginID + ) """; cursor.execute(query) RRM = cursor.fetchone()[0] # Count WW Miss query = """ - SELECT - COUNT(*) - FROM delayedDataBusGaps d, Phases p - WHERE - d.gapBeginCommand = "W" AND - d.gapEndCommand = "W" AND - p.Transact = d.gapEndID AND - PhaseName = "ACT"; + SELECT COUNT(*) FROM + ( + SELECT + COUNT(*) + FROM + delayedDataBusGaps d, Phases p + WHERE + d.gapBeginCommand = "W" AND + d.gapEndCommand = "W" AND + p.Transact = d.gapEndID AND + p.PhaseName = "ACT" + GROUP BY + d.gapBeginID + ) """; cursor.execute(query) WWM = cursor.fetchone()[0] @@ -280,6 +322,7 @@ def delayed_reasons(connection): """; cursor.execute(query) total = cursor.fetchone()[0] + other = total - RW - WR - RRM - WWM RW /= total / 100.0