def load_file_time(traceID, typeID, sizerate=0.1, p=1):
    readReq = 0
    # print(traceID)
    historyHit = 0
    historyReq = 0
    size = int(sizerate*uclnDict[traceID])
    # print(sizerate*uclnDict[traceID], size)
    ssd = PLRU(size, p)
    fin = open(getPath(traceID, typeID), 'r')
    lines = fin.readlines()
    print("load file finished")
    logFile = open(logFilename, "a")
    print(traceID, p, sizerate, size, sep=",", end=",", file=logFile)
    for line in lines:
        items = line.split(' ')
        reqtype = int(items[0])
        blockid = int(items[2])
        if reqtype == 1:            
            ssd.delete_cache(blockid)
        else:       
            if readReq % PERIODLEN == 0 and readReq!=0:
                localHitRatio = 1.0*(ssd.hit-historyHit)/(readReq-historyReq)
                historyHit = ssd.hit
                historyReq = readReq
                print(localHitRatio, sep=",", end=",", file=logFile)
            readReq += 1
            ssd.is_hit(blockid)               
            ssd.update_cache(blockid)
    fin.close()
    print("size", size, p)
    print("total hit rate", 1.0*ssd.hit/readReq, ssd.update)
    
    print(1.0*ssd.hit/readReq, ssd.update, 1.0*ssd.hit/ssd.update, sep=',', file=logFile)
    logFile.close()
예제 #2
0
 def __init__(self, trace, bsizeRatio, csizeRatio, ucln, p, policy):
     self.trace = trace
     self.bsizeRatio = bsizeRatio
     self.cacheSizeRatio = csizeRatio
     # self.p = p
     self.ucln = ucln
     # policy = nrsamples, hit throt, +-s, +-p
     self.policy = policy
     (bp, cp) = p
     self.baseline = PLRU(int(bsizeRatio*ucln), bp)
     # print("base", int(bsizeRatio*ucln), bp)
     self.baseline2 = PLRU(int(csizeRatio*ucln), bp)
     # print("base2", int(csizeRatio*ucln), bp)
     self.cache = PLRU(int(csizeRatio*ucln), cp)
     # print("cache", int(csizeRatio*ucln), cp)
     self.req = 0
     self.lastBaseUpdate = 0
     self.lastCacheUpdate = 0
     self.init_samples()        
예제 #3
0
 def init_samples(self):
     self.samples = []
     self.lastBaseUpdate += self.baseline.get_update()
     self.lastCacheUpdate += self.cache.get_update()
     self.cache.update = 0
     self.baseline.update = 0
     for i in range(-self.policy["nrsamples"], self.policy["nrsamples"]):
         for j in range(-self.policy["nrsamples"], self.policy["nrsamples"]):
             if i == 0 and j == 0:
                 continue
             # print("i=", i, ",j=", j)
             sizeRatio = self.cacheSizeRatio + i * self.policy["deltas"]
             p = self.cache.p + j * self.policy["deltap"]
             # print("sr=", sizeRatio, ",p=", p)
             if is_valid_sp(sizeRatio, p):
                 size = int(sizeRatio*self.ucln)
                 # print("valid", size, p)
                 s = PLRU(int(sizeRatio*self.ucln), p)
                 s.copy(self.cache, size, p)
                 self.samples.append(s)
예제 #4
0
def do_single_trace(traceName, parameters):

    #load trace
    fin = open(traceName, 'r')
    reqs = load_trace(fin)
    fin.close()

    #initial
    baseline = PLRU(parameters.size, parameters.p)
    ssd = PLRU(parameters.size, parameters.p)
    samples = SampleSSDs(parameters, ssd)
    log = Log(parameters)

    for (rw, req) in reqs:
        random.seed()
        roll = random.random()
        #?what about write request?
        update_cache(rw, req, baseline, roll)
        (hit, update) = update_cache(rw, req, ssd, roll)
        samples.update_cache(roll, req, rw, hit, update)
        if log.tick():
            modify_config(samples, ssd, baseline, parameters, log)
    log.print(baseline, ssd)
예제 #5
0
def mtc_test_size_p(path, traceID, totalTimeLength, timeStart, sizerate, p):
    lines = []
    uclnDict = {}
    req = 0
    readReq = 0

    load_lines(path, traceID, totalTimeLength, timeStart, lines, uclnDict)
    size = int(sizerate * len(uclnDict))
    # 稀疏周期,size过小
    if size <= 100:
        return
    print("size=", size)
    ssd = PLRU(size, p)
    for line in lines:
        (time, rw, blockid) = parse_line(line, "gen")
        req += 1
        hit = ssd.is_hit(blockid)
        if rw == 0:
            readReq += 1
        if rw == 1 and hit:
            ssd.add_update()
        ssd.update_cache(blockid)

    print(traceID, "size", size, p)
    print("total hit rate", 1.0 * ssd.hit / req, "update", ssd.update)
    global g

    if ssd.update > 1.0 * size * g * totalTimeLength:
        cost = 1.0 * ssd.update / g / totalTimeLength
    else:
        cost = size
    print(ssd.update, size, g * totalTimeLength,
          1.0 * size * g * totalTimeLength, 1.0 * ssd.update / size, cost)
    logFile = open(logFilename, "a")
    print(traceID,
          timeStart / totalTimeLength,
          totalTimeLength / danwei,
          sizerate,
          size,
          p,
          1.0 * ssd.hit / req,
          ssd.update,
          req,
          round(1.0 * readReq / req, 3),
          cost,
          sep=',',
          file=logFile)
    logFile.close()
예제 #6
0
def handle_csv_time(fileid, filename, order, time, pattern, ssd, fileIdx):
    print("enter handle_csv_time", fileid, order, time, fileIdx)
    flag = False
    readcount = 1
    writecount = 1
    readsize = 1
    writesize = 1
    # outname = filename +'.req'
    count = fileIdx
    totalDict = {}
    readDict = {}
    writeDict = {}
    lba = [[sys.maxsize, 0], [sys.maxsize, 0], [sys.maxsize, 0]]
    infile = open(filename, 'r')
    # outfile = open(outname, 'w')
    nrreq = 0
    lines = infile.readlines()
    if pattern == "warm":
        if fileIdx == 0:
            timeStart = -1
            timeEnd = 10**25
        else:
            line = lines[fileIdx]
            timeBase = get_time(line)
            timeStart = timeBase + order * time
            timeEnd = timeStart + time
        if ssd == None:
            ssd = PLRU(int(0.1 * uclnDict[fileid]), 1)
            oldhit = -1
            oldupdate = -1
        else:
            oldhit = ssd.hit
            oldupdate = ssd.update
    else:
        if order < 0 and fileIdx == 0:
            line = lines[-1]
        else:
            line = lines[fileIdx]
        line = line.strip().split(',')
        timeBase = int(line[0])
        if fileIdx > 0:
            timeStart = timeBase
        else:
            timeStart = timeBase + order * time
        timeEnd = timeStart + time
    print("time", timeBase / danwei, timeStart / danwei, timeEnd / danwei)
    for line in lines[fileIdx:]:
        count += 1
        line = line.strip().split(',')
        timestamp = int(line[0])
        # print(timestamp, timestamp < timeStart, timestamp > timeEnd)
        if timestamp < timeStart:
            continue
        elif timestamp > timeEnd:
            break
        # first coming
        if not flag:
            lineStart = count
            flag = True
        block_id = int((float(line[4])) / block_size)
        block_end = int((float(line[4]) + float(line[5]) - 1) / block_size)
        # if count % 100000 == 0:
        #     print(count)
        if line[3] == 'Write':
            rw = 1
            writecount += 1
            writesize += block_end - block_id + 1
        elif line[3] == 'Read':
            rw = 0
            readcount += 1
            readsize += block_end - block_id + 1
        else:
            rw = 2
        if lba[2][0] > block_id:
            lba[2][0] = block_id
        if lba[2][1] < block_end:
            lba[2][1] = block_end
        if lba[rw][0] > block_id:
            lba[rw][0] = block_id
        if lba[rw][1] < block_end:
            lba[rw][1] = block_end
        for i in range(block_id, block_end + 1):
            # print('{0} {1} {2}'.format(rw,line[2],i),file=outfile)
            # print>>outfile, '{0} {1} {2}'.format(rw,line[2],i)
            totalDict[i] = True

            if rw == 0:
                readDict[i] = True
            elif rw == 1:
                writeDict[i] = True
            if pattern == "warm":
                nrreq += 1
                hit = ssd.is_hit(i)
                if line[3] == 'Write' and hit:
                    ssd.add_update()
                ssd.update_cache(i)
        if pattern == "warm" and oldhit < 0 and ssd.is_full():
            timeBase = timestamp
            timeStart = timeBase + order * time
            timeEnd = timeStart + time
            nrreq = 0
            ssd.oldhit = ssd.hit
            ssd.oldupdate = ssd.update
            readsize = 0
            writesize = 0
            flag = False
    # print("read write", readcount, writecount, readcount/writecount, readsize, writesize, readsize/writesize, sep=',')
    # print("ucln", len(totalDict), len(readDict), len(writeDict),
    # lba[2][1]-lba[2][0]+1, lba[0][1]-lba[0][0]+1, lba[1][1]-lba[1][0]+1, sep=',')
    lineStop = count
    print(fileid,
          pattern,
          order,
          time / danwei,
          readsize,
          writesize,
          round(1.0 * readsize / (readsize + writesize), 2),
          sep=',',
          end=',',
          file=logFile)
    infile.close()
    # outfile.close()
    if pattern != "warm":
        nrreq = 0
        assert len(totalDict) > 0
        ssd = PLRU(int(0.1 * len(totalDict)), 1)
        infile = open(filename, 'r')
        # outfile = open(outname, 'w')
        lines = infile.readlines()
        for line in lines[lineStart - 1:lineStop]:
            line = line.strip().split(',')
            timestamp = int(line[0])
            # if timestamp < timeStart:
            #     continue
            # elif timestamp > timeEnd:
            #     break
            block_id = int((float(line[4])) / block_size)
            block_end = int((float(line[4]) + float(line[5]) - 1) / block_size)
            if count % 100000 == 0:
                print(count)
            for req in range(block_id, block_end + 1):
                nrreq += 1
                hit = ssd.is_hit(req)
                if line[3] == 'Write' and hit:
                    ssd.add_update()
                ssd.update_cache(req)
        hit = ssd.hit
        update = ssd.update
    else:
        hit = ssd.hit - oldhit
        update = ssd.update - oldupdate

    print(fileid, hit, nrreq, 1.0 * hit / nrreq, update)
    print(nrreq,
          ssd.size,
          hit,
          1.0 * hit / nrreq,
          update,
          sep=',',
          file=logFile)
    logFile.flush()
    return (ssd, count)
예제 #7
0
class Cache(object):
    """docstring for Cache"""
    def __init__(self, trace, bsizeRatio, csizeRatio, ucln, p, policy):
        self.trace = trace
        self.bsizeRatio = bsizeRatio
        self.cacheSizeRatio = csizeRatio
        # self.p = p
        self.ucln = ucln
        # policy = nrsamples, hit throt, +-s, +-p
        self.policy = policy
        (bp, cp) = p
        self.baseline = PLRU(int(bsizeRatio*ucln), bp)
        # print("base", int(bsizeRatio*ucln), bp)
        self.baseline2 = PLRU(int(csizeRatio*ucln), bp)
        # print("base2", int(csizeRatio*ucln), bp)
        self.cache = PLRU(int(csizeRatio*ucln), cp)
        # print("cache", int(csizeRatio*ucln), cp)
        self.req = 0
        self.lastBaseUpdate = 0
        self.lastCacheUpdate = 0
        self.init_samples()        

    def init_samples(self):
        self.samples = []
        self.lastBaseUpdate += self.baseline.get_update()
        self.lastCacheUpdate += self.cache.get_update()
        self.cache.update = 0
        self.baseline.update = 0
        for i in range(-self.policy["nrsamples"], self.policy["nrsamples"]):
            for j in range(-self.policy["nrsamples"], self.policy["nrsamples"]):
                if i == 0 and j == 0:
                    continue
                # print("i=", i, ",j=", j)
                sizeRatio = self.cacheSizeRatio + i * self.policy["deltas"]
                p = self.cache.p + j * self.policy["deltap"]
                # print("sr=", sizeRatio, ",p=", p)
                if is_valid_sp(sizeRatio, p):
                    size = int(sizeRatio*self.ucln)
                    # print("valid", size, p)
                    s = PLRU(int(sizeRatio*self.ucln), p)
                    s.copy(self.cache, size, p)
                    self.samples.append(s)
                # sizeRatio = self.cacheSizeRatio - i * self.policy["deltas"]
                # p = self.cache.p - j * self.policy["deltap"]
                # print("sr=", sizeRatio, ",p=", p)
                # if is_valid_sp(sizeRatio, p):
                #     size = int(sizeRatio*self.ucln)
                #     print("valid", size, p)
                #     s = PLRU(size, p)
                #     s.copy(self.cache, size, p)
                #     s.update = 0
                #     self.samples.append(s)

# 修改
    def do_req_help(self, cache, rw, blkid, roll):
        hit = cache.is_hit(blkid) 
        if rw==1 and hit:
            cache.add_update()  #写【驱逐时写回】
        (evicted, update) = cache.update_cache(blkid, roll)
        if update==-1:          # 不需要更新
            update=False
        else:
            update=True
        return (hit, update, evicted)       #返回被驱逐的块以及是否命中
#
    # 极端情况:某个trace在第一个周期内没有req,在get_potential中调用此函数
    # 需要加个条件判断
    def exceed_throt(self, hit, num):
        if self.req == 0:
            return False
        baseline = self.baseline.get_hit()
        h = 1.0*(baseline - hit)/self.req
        # if (hit!=baseline):            
        #     print("baseline", baseline, ",cache", hit, ",Dratio=", h)
        if h > num:
            return True
        return False

    # def get_close_potentials(self):
    #     # print("enter get close potentials")
    #     sizeRatio = self.cacheSizeRatio
    #     size = int(sizeRatio*self.ucln)
    #     p = self.cache.p
    #     pt1 = None
    #     pt2 = None
    #     for pt in self.samples:
    #         if pt.size == size and pt.p==p+self.policy["deltap"]:
    #             pt1 = pt
    # 这个地方代码写的有问题
    #         elif pt.size == size+self.policy["deltas"] and pt.p == p:
    #             pt2 = pt
    #         if pt1!=None and pt2!=None:
    #             return (pt1, pt2)
    #     return (pt1, pt2)

# 修改
    def do_req(self, rw, blkid):
        random.seed()
        roll = random.random()
        self.req += 1
        self.do_req_help(self.baseline, rw, blkid, roll)
        self.do_req_help(self.baseline2, rw, blkid, roll)
        #++
        (hit, update, evicted)=self.do_req_help(self.cache, rw, blkid, roll)
        for s in self.samples:
            self.do_req_help(s, rw, blkid, roll)

        if self.exceed_throt(self.cache.hit, self.policy["throt"]):
            return (True, hit, update, evicted)
        return (False, hit, update, evicted)
    
    # def do_req(self, rw, blkid):
    #     random.seed()
    #     roll = random.random()
    #     self.req += 1
    #     self.do_req_help(self.baseline, rw, blkid, roll)
    #     self.do_req_help(self.baseline2, rw, blkid, roll)
    #     self.do_req_help(self.cache, rw, blkid, roll)
    #     for s in self.samples:
    #         self.do_req_help(s, rw, blkid, roll)
    #     # print("self=", self)
    #     # 命中率过低
    #     if self.exceed_throt(self.cache.hit, self.policy["throt"]):
    #         return True
    #         # print("after self=", self)
    #         # (p1, p2) = self.get_close_potentials()
    #         # if p1==None and p2==None:
    #         #     return (False, self.policy["deltas"], self.policy["deltap"])
    #         # elif p1==None:
    #         #     return (True, (p2.size-self.cache.size, p2.p-self.cache.p), self.policy["deltas"])
    #         # elif p2==None:
    #         #     return (True, (p1.size-self.cache.size, p1.p-self.cache.p), None)
    #         # if p1.get_hit() > p2.get_hit():
    #         #     return (True, (p1.size-self.cache.size, p1.p-self.cache.p), (p2.size-self.cache.size, p2.p-self.cache.p))
    #         # return (True, (p2.size-self.cache.size, p2.p-self.cache.p), (p1.size-self.cache.size, p1.p-self.cache.p))
    #     return False

    def get_hit_scheme_help(self, scheme):
        (s, p) = scheme
        for item in self.samples:
            if item.size == s and item.p == p:
                return item.get_hit()
        return -1

    # 命中率不足时被调用,返回比当前配置和baseline【命中率高一个级别】的(deltas,dtp)列表
    # 返回按照命中率从高到低排序的[(deltas, deltap, hit)]
    def get_hit_scheme(self):
        l = []
        for item in [self.cache, self.baseline]:
            for change in [(int(self.policy["deltas"]*self.ucln),0), (0, self.policy["deltap"])]:
                newSize = item.size
                newP = item.p
                while True:

                    newSize += change[0]
                    newP += change[1]
                    # print(item.size, item.p)
                    # print(newSize, newP)
                    # print("end")

                    if is_valid_sp(1.0*newSize/self.ucln, newP):
                        hit = self.get_hit_scheme_help((newSize, newP))
                        # 如果待改的配置不是potential,默认比item大1
                        if hit == -1:
                            hit = item.get_hit()+1
                            l.append((newSize-self.cache.size, newP-self.cache.p, hit))
                            break
                        elif hit<=item.get_hit():
                            continue
                        else:
                            l.append((newSize-self.cache.size, newP-self.cache.p, hit))
                            break
                    else: #s或者p已经加到越界
                        break
        # l不可能为空
        l.sort(key=lambda item:item[2], reverse=True)
        return l

#修改
    # 确定更改,不存在更改无效的情况
    def change_config(self, s, p):
        # size = s+self.cache.size
        # p = p+self.cache.p
        s = min(int(self.ucln), s)
        (dellist, freenode)=self.cache.change_size(s)
        self.cache.change_p(p)
        return (dellist, freenode)

        # self.cacheSizeRatio = round(1.0*s/self.ucln, 2)
        # print(self.trace, s, p, self.ucln, self.req, self.cacheSizeRatio, self.cacheSizeRatio>=1)
        # assert self.cacheSizeRatio < 1
        # if self.cacheSizeRatio >= 1:
        #     print("trace", self.trace, ",sr=", self.cacheSizeRatio, ",s=", s, "p=", p)
        #     sys.exit(-1)
        # print("sr=", self.cacheSizeRatio)
    
    # give potentials inside the hit range
    # remove bad ones (both s and p are larger)
    def get_potential(self):
        # potentials = []
        results = []
        # print("debug", self.req, self.)
        for sample in self.samples:
            if self.exceed_throt(sample.get_hit(),self.policy["hitThrot"]):
                continue
            # potentials.append(sample)
            # 注释掉优化后加
            results.append((sample.get_size(), sample.get_p(), sample.get_hit(), sample.update))
        # print("sample", sample)
        # 这段是想要优化的,先注释掉吧
        # for i in range(len(potentials)):
        #     sign = False
        #     for j in range(len(potentials)):
        #         # print(i, j, potentials[i].size, potentials[j].size, potentials[i].update, potentials[j].update)
        #         # print(sign)
        #         if i==j:
        #             continue
        #         if potentials[i].size >= potentials[j].size and potentials[i].update >= potentials[j].update:
        #             sign = True
        #             break
        #     # print(sign)
        #     if not sign:
        #         # print("debug", potentials[i].get_size(), potentials[i].get_update(), potentials[i].get_p())
            # results.append(potentials[i])
        if self.exceed_throt(self.cache.get_hit(),self.policy["hitThrot"]):
            sample = self.cache
            results.append((sample.get_size(), sample.get_p(), sample.get_hit(), sample.update))
        sample = self.baseline
        results.append((sample.get_size(), sample.get_p(), sample.get_hit(), sample.update))
        return results
    
    # 因为中间计算时把cache的update减去了,这里加回来
    def finish(self):
        self.baseline.update += self.lastBaseUpdate
        self.cache.update += self.lastCacheUpdate
        
                    
예제 #8
0
def load_file(traceID, typeID, sizerate=0.1, p=1, mode='w'):
    readReq = 0
    size = int(sizerate * uclnDict[traceID])
    ssd = PLRU(size, p)
    fin = open(getPath(traceID, typeID), 'r')
    lines = fin.readlines()
    req = 0
    myupdate = 0
    minTime = None
    maxTime = None
    print("load file finished")
    for line in lines:
        items = line.strip().split(' ')
        reqtype = int(items[0])
        blockid = int(items[2])
        if mode == 'r':
            if reqtype == 1:
                ssd.delete_cache(blockid)
            else:
                readReq += 1
                if readReq % 1000000 == 0:
                    print(readReq)
                req += 1
                ssd.is_hit(blockid)
                ssd.update_cache(blockid)
        else:
            req += 1
            hit = ssd.is_hit(blockid)
            if reqtype == 0:
                readReq += 1
            if reqtype == 1 and hit:
                ssd.add_update()
                myupdate += 1
            ssd.update_cache(blockid)
            if not hit and ssd.get_top_n(1) == [blockid]:
                myupdate += 1
    fin.close()
    print(traceID, "size", size, p, "myupdate", myupdate)
    print("total hit rate", 1.0 * ssd.hit / req, ssd.update)
    logFile = open(logFilename, "a")
    print(traceID,
          p,
          sizerate,
          size,
          1.0 * ssd.hit / req,
          ssd.update,
          req,
          round(1.0 * readReq / req, 3),
          minTime,
          maxTime,
          sep=',',
          file=logFile)
    logFile.close()