accessAnalyzer のソースコード

#!
# coding: utf-8
# Copyright (C) 2016 TOPS SYSTEMS
### @file accessAnalyzer.py
### @brief access pattern Analyzer
###
### ISIMのLOGファイルを解析し、アクセスマップを生成するプログラム
### Contact: izumida@topscom.co.jp
###
### @author: M.Izumida
### @date: June 10, 2016
###
## v01r01 2016/06/10 newly created.
## v01r02 2016/06/13 複数リージョンのR/Wに対応できるように.
##
# Written for Python 2.7 (NOT FOR 3.x)
#=======================================================================
# インポート宣言
from __future__ import division
import sys
import re
import argparse
import os
from datetime import datetime
import numpy as np
#=======================================================================
# バージョン文字列
versionSTR = "accessAnalyzer.py v01r02 Tops Systems (pgm by mpi)"
#=======================================================================
# 共通サブルーチン
#-------------------------------------------------------------------
def errPrint(mes):
    """errPrint.

    エラー出力へのメッセージ表示
    後の始末はその後で別に書くこと
    """
    sys.stderr.write(mes)
    sys.stderr.write('\n')

#-------------------------------------------------------------------
def stdExceptionHandler(mes):
    """standard Exception Handler.

    エラーメッセージを送出し、デバッグのための情報を出力する
    """
    errPrint("Exception Captured: " + str(mes))
    errPrint("0:" + str(sys.exc_info()[0]))
    errPrint("1:" + str(sys.exc_info()[1]))
    errPrint("2:" + str(sys.exc_info()[2]))

#-------------------------------------------------------------------
def tryIntParse(st, dval, radix=10):
    """try Parse string to Integer

    文字列stをパースして整数化できれば値を返す、できなければデフォルト値dvalを返す
    """
    try:
        work = int(st, radix)
    except:
        return dval
    return work

#=======================================================================
# Access Checkerクラス
[ドキュメント]class AccessChecker: """Access Checker Class. 与えられた行を解釈し、アクセス履歴をnumpy 配列形式で記録するクラス """ #-------------------------------------------------------------------- def __init__(self, w, eSize, h, lm1, lm2, sz1, sz2, opt=False): """Access Checker Constructor コンストラクタ """ self.dWidth = w self.eSize = eSize self.lineWidth = self.dWidth // eSize self.dHeight = h self.LowLimit1 = lm1 self.LowLimit2 = lm2 self.HighLimit1 = self.LowLimit1 + sz1 self.HighLimit2 = self.LowLimit2 + sz2 # self.yMin = [self.dHeight, self.dHeight] self.xMin = [self.lineWidth, self.lineWidth] self.yMax = [0, 0] self.xMax = [0, 0] # self.datArray = np.zeros([self.dHeight, self.lineWidth, 2]) #Y, X, region #高速化のためマッチパターンをコンパイルしておく if opt: self.p0match = re.compile('MWR([LDWB]):([0-9A-Fa-f]{8}):([0-9A-Fa-f\&]+)') else: self.p0match = re.compile('MRD([LDWB]):([0-9A-Fa-f]{8}):([0-9A-Fa-f\&]+)') #Access core self.accessCoreList0 = [] self.accessCoreList1 = [] #デバッグ self.debug = False self.verbose = False #--------------------------------------------------------------------
[ドキュメント] def rLine(self, lin): """Read Line method 読み取った1行を処理するメソッド。 ①メモリアクセスを探す ②メモリアクセスのアドレスが範囲内かどうか調べる ③範囲内であれば配列にアクセス回数を書き込む(更新する) 継続ならFalseを返す。エラーがあればTrueを返して脱出 """ elemLis = lin.split() region = 0 if len(elemLis) > 0: accessCore = elemLis[0] for elem in elemLis: p0 = self.p0match.match(elem) if p0: adr = tryIntParse(p0.group(2), 0, 16) if (self.HighLimit1 > adr ) and (adr >= self.LowLimit1): region = 0 yAdr = (adr - self.LowLimit1) // self.dWidth xAdr = ((adr - self.LowLimit1) % self.dWidth) // self.eSize elif (self.HighLimit2 > adr ) and (adr >= self.LowLimit2): region = 1 yAdr = (adr - self.LowLimit2) // self.dWidth xAdr = ((adr - self.LowLimit2) % self.dWidth) // self.eSize else: return False if yAdr < self.yMin[region]: self.yMin[region] = yAdr if xAdr < self.xMin[region]: self.xMin[region] = xAdr if yAdr > self.yMax[region]: self.yMax[region] = yAdr if xAdr > self.xMax[region]: self.xMax[region] = xAdr self.datArray[yAdr, xAdr, region] += 1 if region == 0: if accessCore not in self.accessCoreList0: self.accessCoreList0.append(accessCore) else: if accessCore not in self.accessCoreList1: self.accessCoreList1.append(accessCore) return False
#--------------------------------------------------------------------
[ドキュメント] def accessLog(self, region): """dump access log アクセスログを表示する。 """ if region == 0: print print "--- BUF A --- ", for core in self.accessCoreList0: print core, else: print print "--- BUF B --- ", for core in self.accessCoreList1: print core, print "yMin=", self.yMin[region], "yMax=", self.yMax[region], "xMin=", self.xMin[region], "xMax=", self.xMax[region] for yAdr in range(0, self.dHeight): print "{0:>3d} ".format(yAdr), for xAdr in range(0, self.lineWidth): cnt = self.datArray[yAdr, xAdr, region] if cnt > 9: pchr = "*" elif cnt == 0: pchr = "_" else: pchr = str(int(cnt)) print "{0:1}".format(pchr), print
#======================================================================= # Direct LOGファイルリーダクラス
[ドキュメント]class DirectLogReader: """Direct LOG File Reader Class. LOGファイル(命令実行ログ形式)を読み取ってAccessCheckerクラスを駆動する """ #-------------------------------------------------------------------- def __init__(self, fnam, imageNFlag, blockFlag, dbg, vbs): """Direct LOG File Reader Constructor コンストラクタ """ self.logFname = fnam # self.imageFlag = not imageNFlag self.blockFlag = blockFlag #デバッグ self.debug = dbg self.verbose = vbs # if self.imageFlag: self.imageAccess = AccessChecker(640, 32, 350, 0x60000000, 0x6004B000, 640*350, 640*350, False) #Read self.imageAccess.debug = dbg self.imageAccess.verbose = vbs if self.blockFlag: self.blockAccessR = AccessChecker(64, 2, 25, 0x600FD000, 0x600FD640, 1600, 1600, False) #Read self.blockAccessR.debug = dbg self.blockAccessR.verbose = vbs self.blockAccessW = AccessChecker(64, 32, 25, 0x600FD000, 0x600FD640, 1600, 1600, True) #True self.blockAccessW.debug = dbg self.blockAccessW.verbose = vbs #--------------------------------------------------------------------
[ドキュメント] def read(self): """read method ファイルから行をリードして処理するメソッド """ try: with open(self.logFname, 'r') as f: for line in f: if self.rLine(line): break except: stdExceptionHandler("ERROR: in file reading = " + self.logFname) return False return True
#--------------------------------------------------------------------
[ドキュメント] def rLine(self, lin): """Read Line method 読み取った1行を処理するメソッド """ result = False if self.imageFlag: result = result or self.imageAccess.rLine(lin) if self.blockFlag: result = result or self.blockAccessR.rLine(lin) result = result or self.blockAccessW.rLine(lin) return result
#--------------------------------------------------------------------
[ドキュメント] def accessLog(self): """dump access log アクセスログを表示する。 """ if self.imageFlag: print print "IMAGE BUF" self.imageAccess.accessLog(0) self.imageAccess.accessLog(1) if self.blockFlag: print print "BLOCK MATCH BUF Write Access" self.blockAccessW.accessLog(0) self.blockAccessW.accessLog(1) print print "BLOCK MATCH BUF Read Access" self.blockAccessR.accessLog(0) self.blockAccessR.accessLog(1)
#======================================================================= # メインプログラム def main(): """main. メインプログラム """ #----------------------------------------------------------------------- # コマンドラインオプション処理 # parser = argparse.ArgumentParser(description='accessAnalyzer.') parser.add_argument('--LOG', nargs=1, help='Specify LOG file name.') parser.add_argument('-iN', dest='image', help='Image Buffer Read.', action='store_true', default=False) parser.add_argument('-b', dest='block', help='Block Match Read/Write.', action='store_true', default=False) parser.add_argument('-d', dest='debug', help='Debug mode, print debug information.', action='store_true', default=False) parser.add_argument('-v', dest='verbose', help='Verbose mode.', action='store_true', default=False) parser.add_argument('-V', dest='VERSION', help='Show Version, then exit', action='store_true', default=False) args = parser.parse_args() #----------------------------------------------------------------------- # Version 表示 # print versionSTR if args.VERSION: sys.exit(0) #----------------------------------------------------------------------- # ファイル名処理 # if args.LOG is None: errPrint('ERROR: NO input LOG file!!!') sys.exit(1) else: logFname = args.LOG[0] if not os.path.isfile(logFname): errPrint('ERROR: LOG file, NOT EXIST.') sys.exit(1) #----------------------------------------------------------------------- # パラメータ処理 #----------------------------------------------------------------------- # 実処理 # data = DirectLogReader(logFname, args.image, args.block, args.debug, args.verbose) if data.read(): data.accessLog() else: sys.exit(1) #終了メッセージ today = datetime.today() print "-" * 50 print today.strftime("FINISH: %Y/%m/%d %H:%M:%S") #----------------------------------------------------------------------- # 正常終了 # sys.exit(0) #======================================================================= # メインプログラムの起動 if __name__ == "__main__": main()