Fix metrics for HBM PC mode.

This commit is contained in:
Lukas Steiner
2022-04-04 10:54:08 +02:00
parent fac18ed81b
commit 1bda9f7dd4
2 changed files with 60 additions and 48 deletions

View File

@@ -1,4 +1,5 @@
import json
from sqlite3.dbapi2 import Cursor
class MCConfig(object):
""" Memory Controller Configuration Class
@@ -50,7 +51,7 @@ def getClock(dbconnection):
def getNumberOfTransactions(dbconnection):
cursor = dbconnection.cursor()
cursor.execute("SELECT NumberOfTransactions FROM generalInfo")
cursor.execute("SELECT NumberOfTransactions FROM GeneralInfo")
result = cursor.fetchone()
return result[0]
@@ -62,44 +63,57 @@ def getTraceEndTime(dbconnection):
def getNumberOfBanks(dbconnection):
cursor = dbconnection.cursor()
cursor.execute("SELECT NumberOfBanks FROM generalInfo")
cursor.execute("SELECT NumberOfBanks FROM GeneralInfo")
result = cursor.fetchone()
return result[0]
def getNumberOfRanks(dbconnection):
cursor = dbconnection.cursor()
cursor.execute("SELECT NumberOfRanks FROM generalInfo")
cursor.execute("SELECT NumberOfRanks FROM GeneralInfo")
result = cursor.fetchone()
return result[0]
def getNumberOfBankGroups(dbconnection):
cursor = dbconnection.cursor()
cursor.execute("SELECT NumberOfBankGroups FROM generalInfo")
cursor.execute("SELECT NumberOfBankGroups FROM GeneralInfo")
result = cursor.fetchone()
return result[0]
def getPer2BankOffset(dbconnection):
cursor = dbconnection.cursor()
cursor.execute("SELECT Per2BankOffset FROM generalInfo")
cursor.execute("SELECT Per2BankOffset FROM GeneralInfo")
result = cursor.fetchone()
return result[0]
def getWindowSize(connection):
cursor = connection.cursor()
cursor.execute(" SELECT WindowSize FROM GeneralInfo ")
cursor.execute("SELECT WindowSize FROM GeneralInfo")
windowSize = float(cursor.fetchone()[0])
return windowSize
def getRowColumnCommandBus(connection):
cursor = connection.cursor()
cursor.execute("SELECT RowColumnCommandBus FROM GeneralInfo")
return bool(cursor.fetchone()[0])
def getPseudoChannelMode(connection):
cursor = connection.cursor()
cursor.execute("SELECT PseudoChannelMode FROM GeneralInfo")
return bool(cursor.fetchone()[0])
def maximum_data_rate(connection):
memspec = MemSpec(connection)
try:
width = memspec.getIntValue("memarchitecturespec", "nbrOfDevicesOnDIMM") * memspec.getIntValue("memarchitecturespec", "width")
width = memspec.getIntValue("memarchitecturespec", "nbrOfDevices") * memspec.getIntValue("memarchitecturespec", "width")
except:
width = memspec.getIntValue("memarchitecturespec", "width")
clk = memspec.getIntValue("memtimingspec", "clkMhz")
rate = memspec.getIntValue("memarchitecturespec", "dataRate")
maxDataRate = float(clk) * float(width) * float(rate)
if getPseudoChannelMode(connection):
maxDataRate = float(clk) * float(width) * float(rate) * 2
else:
maxDataRate = float(clk) * float(width) * float(rate)
return maxDataRate

View File

@@ -39,9 +39,7 @@ def trace_length_in_ns(connection):
@metric
def command_bus_utilisation_in_percent(connection):
cursor = connection.cursor()
cursor.execute("""SELECT RowColumnCommandBus FROM GeneralInfo""")
rowColumnCommandBus = cursor.fetchone()[0]
if rowColumnCommandBus:
if getRowColumnCommandBus(connection):
cursor.execute("""
SELECT SUM(CommandLengths.Length)
FROM Phases
@@ -135,6 +133,14 @@ def average_wr_response_latency_in_ns(connection):
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 """)
result = cursor.fetchone()
return result[0]
@metric
def max_rd_response_latency_in_ns(connection):
cursor = connection.cursor()
@@ -177,15 +183,6 @@ def max_wr_response_latency_in_ns(connection):
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 """)
result = cursor.fetchone()
return result[0]
@metric
def trans_with_max_response_latency(connection):
cursor = connection.cursor()
@@ -195,23 +192,25 @@ def trans_with_max_response_latency(connection):
return result[0]
@metric
def memory_active(connection):
def memory_active_in_clks(connection):
cursor = connection.cursor()
cursor.execute(""" SELECT sum(DataStrobeEnd - DataStrobeBegin) FROM transactions """)
active = cursor.fetchone()
clk, unit = getClock(connection)
return (active[0]/clk)
cursor.execute("""SELECT sum(DataStrobeEnd - DataStrobeBegin) FROM Transactions""")
active = cursor.fetchone()[0]
if getPseudoChannelMode(connection):
active /= 2
clk, _ = getClock(connection)
return (active / clk)
@metric
def memory_total(connection):
def memory_total_in_clks(connection):
cursor = connection.cursor()
cursor.execute(""" SELECT max(DataStrobeEnd) FROM Transactions """)
total = cursor.fetchone()
clk, unit = getClock(connection)
clk, _ = getClock(connection)
return (total[0]/clk)
@metric
def memory_idle(connection):
def memory_idle_in_clks(connection):
# This complex query identifies idle times where the DRAM is not used.
# The code works also if schedulers are used.
@@ -276,10 +275,10 @@ def memory_idle(connection):
return ((idle[0] + idle_start[0]) / clk)
@metric
def memory_delayed(connection):
total = memory_total(connection)
active = memory_active(connection)
idle = memory_idle(connection)
def memory_delayed_in_clks(connection):
total = memory_total_in_clks(connection)
active = memory_active_in_clks(connection)
idle = memory_idle_in_clks(connection)
return total - active - idle
@metric
@@ -392,7 +391,7 @@ def delayed_reasons(connection):
WHERE
gapBeginCommand = "R" AND
gapEndCommand = "W";
""";
"""
cursor.execute(query)
RW = cursor.fetchone()[0]
@@ -405,7 +404,7 @@ def delayed_reasons(connection):
WHERE
gapBeginCommand = "W" AND
gapEndCommand = "R";
""";
"""
cursor.execute(query)
WR = cursor.fetchone()[0]
@@ -425,7 +424,7 @@ def delayed_reasons(connection):
GROUP BY
d.gapBeginID
)
""";
"""
cursor.execute(query)
RRM = cursor.fetchone()[0]
@@ -445,7 +444,7 @@ def delayed_reasons(connection):
GROUP BY
d.gapBeginID
)
""";
"""
cursor.execute(query)
WWM = cursor.fetchone()[0]
@@ -454,7 +453,7 @@ def delayed_reasons(connection):
SELECT
COUNT(*)
FROM delayedDataBusGaps;
""";
"""
cursor.execute(query)
total = cursor.fetchone()[0]
@@ -466,25 +465,25 @@ def delayed_reasons(connection):
WWM /= total / 100.0
other /= total / 100.0
result = "RW: {}, WR: {}, RRM: {}, WWM: {}, Other: {}".format(RW, WR, RRM, WWM, other);
result = "RW: {}, WR: {}, RRM: {}, WWM: {}, Other: {}".format(RW, WR, RRM, WWM, other)
return result
@metric
def memory_idle_in_percent(connection):
total = memory_total(connection)
idle = memory_idle(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(connection)
active = memory_active(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(connection)
delayed = memory_delayed(connection)
total = memory_total_in_clks(connection)
delayed = memory_delayed_in_clks(connection)
return (delayed/total)*100
@metric
@@ -493,12 +492,11 @@ def memory_idle_active_delayed_check(connection):
@metric
def memory_utilisation_percent_without_idle(connection):
total = memory_total(connection)
active = memory_active(connection)
idle = memory_idle(connection)
total = memory_total_in_clks(connection)
active = memory_active_in_clks(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.