180 lines
6.5 KiB
Python
180 lines
6.5 KiB
Python
import sys
|
|
import sqlite3
|
|
|
|
metrics = []
|
|
threadMetrics = []
|
|
|
|
def metric(function):
|
|
metrics.append(function)
|
|
return function
|
|
|
|
def threadMetric(function):
|
|
threadMetrics.append(function)
|
|
return function
|
|
|
|
def getThreads(connection):
|
|
cursor = connection.cursor()
|
|
cursor.execute("SELECT DISTINCT(TThread) FROM transactions WHERE TThread != 0 ORDER BY TThread")
|
|
result = []
|
|
for currentRow in cursor:
|
|
result.append(currentRow[0])
|
|
return result
|
|
|
|
def getNumberOfBanks(connection):
|
|
cursor = connection.cursor()
|
|
cursor.execute("SELECT NumberOfBanks FROM generalInfo")
|
|
result = cursor.fetchone()
|
|
return result[0]
|
|
|
|
def getTraceLength(connection):
|
|
cursor = connection.cursor()
|
|
cursor.execute("SELECT TraceEnd FROM GeneralInfo")
|
|
result = cursor.fetchone()
|
|
return result[0]
|
|
|
|
@metric
|
|
def average_response_latency_in_ns(connection):
|
|
cursor = connection.cursor()
|
|
cursor.execute("""SELECT avg(ranges.end-ranges.begin) FROM transactions INNER JOIN ranges
|
|
ON transactions.range = ranges.ID where TThread != 0""")
|
|
|
|
result = cursor.fetchone()
|
|
return round(result[0],1)
|
|
|
|
@threadMetric
|
|
def average_response_latency_in_ns(connection, thread):
|
|
cursor = connection.cursor()
|
|
query = """SELECT avg(ranges.end-ranges.begin) FROM transactions INNER JOIN ranges
|
|
ON transactions.range = ranges.ID where TThread = :Thread """
|
|
|
|
cursor.execute(query, {"Thread": thread})
|
|
result = cursor.fetchone()
|
|
return round(result[0],1)
|
|
|
|
@metric
|
|
def number_of_activates(connection):
|
|
cursor = connection.cursor()
|
|
cursor.execute("SELECT COUNT(*) FROM Phases WHERE PhaseName = 'ACT'")
|
|
result = cursor.fetchone()
|
|
return result[0]
|
|
|
|
@metric
|
|
def number_of_precharges(connection):
|
|
cursor = connection.cursor()
|
|
cursor.execute("SELECT COUNT(*) FROM Phases WHERE PhaseName IN ('PRE','PRE_ALL','RDA','WRA')")
|
|
result = cursor.fetchone()
|
|
return result[0]
|
|
|
|
|
|
def timeInPowerStates(connection):
|
|
totalTimeAllBanks = getTraceLength(connection)*getNumberOfBanks(connection)
|
|
cursor = connection.cursor()
|
|
result = []
|
|
|
|
cursor.execute("SELECT SUM(PhaseEnd-PhaseBegin) from Phases where PhaseName = 'PDNA'")
|
|
timeInPDNA = cursor.fetchone()
|
|
totalTimeInPDNA = timeInPDNA[0]
|
|
if(totalTimeInPDNA == None):
|
|
totalTimeInPDNA = 0.0
|
|
fractionInPDNA = totalTimeInPDNA*1.0/totalTimeAllBanks
|
|
result.append(("Time in PDNA (%)", fractionInPDNA*100))
|
|
print("{0} {1}".format(result[-1][0],result[-1][1]))
|
|
|
|
cursor.execute("SELECT SUM(PhaseEnd-PhaseBegin) from Phases where PhaseName = 'PDNP'")
|
|
timeInPDNP = cursor.fetchone()
|
|
totalTimeInPDNP = timeInPDNP[0]
|
|
if(totalTimeInPDNP == None):
|
|
totalTimeInPDNP = 0.0
|
|
fractionInPDNP = totalTimeInPDNP*1.0/totalTimeAllBanks
|
|
result.append(("Time in PDNP (%)", fractionInPDNP*100))
|
|
print("{0} {1}".format(result[-1][0],result[-1][1]))
|
|
|
|
cursor.execute("SELECT SUM(PhaseEnd-PhaseBegin) from Phases where PhaseName = 'SREF'")
|
|
timeInSREF = cursor.fetchone()
|
|
totalTimeInSREF = timeInSREF[0]
|
|
if(totalTimeInSREF == None):
|
|
totalTimeInSREF = 0.0
|
|
fractionInSREF = totalTimeInSREF*1.0/totalTimeAllBanks
|
|
result.append(("Time in SREF (%)", fractionInSREF*100))
|
|
print("{0} {1}".format(result[-1][0],result[-1][1]))
|
|
result.insert(0,("Active time (%)", (1-fractionInPDNA-fractionInPDNP-fractionInSREF)*100))
|
|
print("{0} {1}".format(result[0][0],result[0][1]))
|
|
|
|
return result
|
|
|
|
def passRatio(connection):
|
|
|
|
numberOfPassWins = {}
|
|
numberOfPassLosses = {}
|
|
|
|
for thread in getThreads(connection):
|
|
numberOfPassWins[thread] = 0
|
|
numberOfPassLosses[thread] = 0
|
|
|
|
for bankNumber in range(getNumberOfBanks(connection)):
|
|
cursor = connection.cursor()
|
|
query = """SELECT begin,end,transactions.ID,TThread,
|
|
TBank from transactions inner join ranges on transactions.range = ranges.id WHERE TBank = :Bank AND TThread != 0"""
|
|
cursor.execute(query, {"Bank":bankNumber})
|
|
|
|
for passedRequest in cursor:
|
|
passedBegin = passedRequest[0]
|
|
passedEnd = passedRequest[1]
|
|
passedId = passedRequest[2]
|
|
passedThread = passedRequest[3]
|
|
|
|
cursor2 = connection.cursor()
|
|
query2 = """SELECT begin,end,transactions.ID,TThread,
|
|
TBank from transactions inner join ranges on transactions.range = ranges.id
|
|
WHERE TBank = :Bank AND :Begin<begin AND end<:End AND TThread != :Thread AND TThread != 0"""
|
|
cursor2.execute(query2, {"Bank" : bankNumber, "Thread": passedThread, "Begin" : passedBegin, "End" : passedEnd})
|
|
|
|
for passingRequest in cursor2:
|
|
numberOfPassLosses[passedThread] += 1
|
|
numberOfPassWins[passingRequest[3]] += 1
|
|
# print("""Transaction {0} (thread:{1} begin:{2} end:{3}) was passed by Transaction {4} (thread:{5} begin:{6} end:{7}) on bank {8}""".format(passedId,passedThread, passedBegin,passedEnd,
|
|
# passingRequest[2], passingRequest[3], passingRequest[0], passingRequest[1], bankNumber))
|
|
|
|
result = []
|
|
for thread in getThreads(connection):
|
|
totalPassedInvolved = numberOfPassWins[thread]+numberOfPassLosses[thread]
|
|
if(totalPassedInvolved > 0):
|
|
passRatio = numberOfPassWins[thread]*1.0/(numberOfPassWins[thread]+numberOfPassLosses[thread])
|
|
else:
|
|
passRatio = 0.5
|
|
print("Thread {0} passed other threads {1} times and was passed {2} times. Pass ratio is {3}".format
|
|
(thread, numberOfPassWins[thread], numberOfPassLosses[thread],passRatio))
|
|
result.append(("Thread {0} pass ratio".format(thread), passRatio))
|
|
return result
|
|
|
|
|
|
|
|
def calculateMetrics(pathToTrace):
|
|
connection = sqlite3.connect(pathToTrace)
|
|
calculatedMetrics = []
|
|
|
|
print("================================")
|
|
print("Calculating metrics for {0}".format(pathToTrace))
|
|
|
|
|
|
for metric in metrics:
|
|
res = (metric.__name__.replace("_"," "), metric(connection))
|
|
print("{0}: {1}".format(res[0],res[1]))
|
|
calculatedMetrics.append(res)
|
|
|
|
for thread in getThreads(connection):
|
|
for metric in threadMetrics:
|
|
res = ("Thread " + str(thread) + " " + metric.__name__.replace("_"," "), metric(connection, thread))
|
|
print("{0}: {1}".format(res[0],res[1]))
|
|
calculatedMetrics.append(res)
|
|
|
|
calculatedMetrics.extend(passRatio(connection))
|
|
calculatedMetrics.extend(timeInPowerStates(connection))
|
|
|
|
connection.close()
|
|
return calculatedMetrics
|
|
|
|
if __name__ == "__main__":
|
|
path = sys.argv[1]
|
|
calculateMetrics(path)
|
|
|