123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489 |
- /*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
- package cache;
- import java.util.ArrayList;
- /**
- *
- * @author Juninho Carlos
- */
- public class Cache {
-
- private long escritaCache; //Ultimo contador que fiz
- private long leituraCache; //done
- private long escritaRedundancia; //done
- private long leituraRedundancia;
-
- private long contadorDeCiclos; //feito
- private long contadorDeWB; //feito
- private long contadorDeWBForcado; //feito
-
- private long contadorDeLeituraEspecial; //feito
-
- private long contadorDeHit; //feito
- private long contadorDeMiss; //feito
-
- private long ContadorIncachavel;
-
- private long escritaSDRAM;
- private long leituraSDRAM;
-
- private Redundancia redundancia;
- private Conjunto[] conjuntos;
- public Cache() {
- this.redundancia = new Redundancia();
-
- this.escritaCache = 0;
- this.escritaRedundancia = 0;
-
- this.leituraCache = 0;
- this.leituraRedundancia = 0;
-
-
-
- this.contadorDeCiclos = 0;
- this.contadorDeWB = 0;
- this.contadorDeWBForcado = 0;
- this.contadorDeLeituraEspecial = 0;
-
- this.contadorDeHit = 0;
- this.contadorDeMiss = 0;
-
- this.ContadorIncachavel = 0;
-
- this.escritaSDRAM = 0;
- this.leituraSDRAM = 0;
-
- this.conjuntos = new Conjunto[32];
- for (int i = 0; i < 32; i++) {
- this.conjuntos[i] = new Conjunto();
- }
- }
-
- public long getEscritaSDRAM(){
- return this.escritaSDRAM;
- }
-
- public long getLeituraSDRAM(){
- return this.leituraSDRAM;
- }
- public long getContadorIncachavel(){
- return this.ContadorIncachavel;
- }
-
- public long getcontadorLeituraEspecial(){
- return this.contadorDeLeituraEspecial;
- }
- public long getWBForcado(){
- return this.contadorDeWBForcado;
- }
-
- public long getHit(){
- return this.contadorDeHit;
- }
-
- public long getMiss(){
- return this.contadorDeMiss;
- }
-
- public long getEscritaCache(){
- return this.escritaCache;
- }
-
- public long getEscritaRedundancia(){
- return this.escritaRedundancia;
- }
-
- public long getLeituraCache(){
- return this.leituraCache;
- }
-
- public long getLeituraRedundancia(){
- return this.leituraRedundancia;
- }
-
- /**
- *
- * @param address endereço solicitado à cache
- * @param read true -> leitura(lw), false -> escrita(sw)
- */
- public void requisicaoParaCache(long address, boolean read) {
- Requisicao end = new Requisicao(address, read);
- // System.out.println("pal = "+end.palavra);
- if (isHit(end)) { //Verifica se é hit, e, se for, atualiza o bit de sujeira, caso necessário.
-
- this.contadorDeHit++;
-
- // System.err.println("HIT: endereco: " + end.endereco);
- // System.err.println("");
- if (read) {
- this.contadorDeCiclos += ConstanteDeTempo.hit_read;
- } else {
- this.contadorDeCiclos += ConstanteDeTempo.hit_write; //contabiliza ciclos, inclusive os da comparação
- }
-
- int bloco = this.conjuntos[end.conjunto].getBlocoFromReq(end);
-
- boolean erro = this.conjuntos[end.conjunto].getBloco(bloco).getErroFromPalavra(end.palavra);
- if(!read){
- if(erro){
- this.escritaRedundancia++;
- }else{
- this.escritaCache++;
- }
- }else{
- if(erro){
- this.leituraRedundancia++;
- }else{
- this.leituraCache++;
- }
- }
- //Tem que atualizar bit de sujeira caso seja escrita
- //Deu hit e tem que verificar se tá na cache ou na redundancia
- //contadorDeHit++;
- } else {
- //Deu miss
- //System.err.println("MISS " + address);
- this.contadorDeMiss++;
-
- if (read) {
- this.contadorDeCiclos += ConstanteDeTempo.leitura_miss;
- } else {
- this.contadorDeCiclos += ConstanteDeTempo.escrita_miss;
- }
- this.requisicaoDeBlocoNoConjunto(end);
- //conjuntos[end.conjunto].requisicaoDeBlocoNoConjunto(end,this.redundancia);
- }
- }
- public void inserirErroRedundancia(int conjunto, int bloco, int palavra) {
- this.redundancia.inserirErro(conjunto, bloco, palavra);
- }
- private ArrayList<Integer> escreverBlocoNaRed(Requisicao requisicao, int bloco) {
-
- Requisicao req = new Requisicao(requisicao.endereco, requisicao.read);
-
- ArrayList<Integer> enderecosToWB = new ArrayList<>();
- Conjunto c = this.conjuntos[req.conjunto];
- for (int i = 0; i < 32; i++) {
- Requisicao aux = req;
- aux.palavra = i;
- if (c.getBloco(bloco).getErroDasPalavraDoBloco()[i]) {
-
- this.contadorDeCiclos += 3; //1 ciclo para escreve, um para ler, outro para comparar
- this.leituraRedundancia++;
- this.escritaRedundancia++;
-
- Integer numToWB = redundancia.escreverPalavraNaRedMiss(aux, bloco);
- if (numToWB != null && numToWB == -1) {
- //Deu bosta
- ArrayList<Integer> bosta = new ArrayList<>();
- bosta.add(-1);
- return bosta;
- }
- if (numToWB != null) {
- if (!c.arrayHasTheValue(enderecosToWB, numToWB)) {
- enderecosToWB.add(numToWB);
- }
- }
- }else{
- this.escritaCache++;
- }
- }
- return enderecosToWB;
- }
- private void leituraEspecial(int tag, int bloco) {
- this.leituraRedundancia += 32;
- this.redundancia.leituraEspecial(tag, tag % 4, bloco);
- }
- /**
- * Escreve palavra com erro na redundancia e faz os wb forçados/LE dos
- * blocos necessários
- *
- * @param req
- * @param c
- *
- * Retorna true quando detecta o erro na redundacia e false quando ñ tem
- * erro na red
- */
- private boolean trataBlocoComErro(Requisicao req, Conjunto c, int bloco) {
- ArrayList<Integer> enderecosToWB = escreverBlocoNaRed(req, bloco);
- if (enderecosToWB.size() == 1 && enderecosToWB.get(0) == -1) { //Tentou escrever na Red e deu erro
- return true;
- }
- if (enderecosToWB.size() > 0) { //Tratar WBs ou LE
- //Requisicao r = new Requisicao(RR, true)
- // System.err.println("Fazendo WB forçado");
- // System.err.println("conjuntos wbackado/LE: " + enderecosToWB.toString());
- // System.err.println("bloco: " + bloco);
- for (Integer integer : enderecosToWB) {
- this.leituraEspecial(integer, bloco);
- Conjunto wb = this.conjuntos[integer];
- if (wb.getBlocos()[bloco].isSujo()) {
- //Faz WB-FORCADO
- // System.err.println("Fazendo WB-forcado do conjunto " + integer);
-
- this.contadorDeWBForcado++;
- this.contadorDeCiclos += ConstanteDeTempo.WB;
- this.leituraRedundancia += 32;
- this.escritaSDRAM += 32;
- wb.desalocaBloco(bloco);
- } else {
- // System.err.println("Fazendo LE do conjunto " + integer);
- //Contabilizar leitura especial
- this.contadorDeLeituraEspecial++;
- this.leituraRedundancia+=32;
- this.contadorDeCiclos += ConstanteDeTempo.leitura_especial;
- wb.desalocaBloco(bloco);
- }
- }
- }
- return false;
- }
- public long getWB(){
- return this.contadorDeWB;
- }
- public long getCiclos(){
- return this.contadorDeCiclos;
- }
-
- private void tratarWB(Requisicao req, int numBloco) {
- Conjunto c = this.conjuntos[req.conjunto];
-
- if (c.getBloco(numBloco).hasErrorInBloco()) {
- this.leituraEspecial(req.conjunto, numBloco);
- if(!c.getBloco(numBloco).isSujo()){
- //Só contabiliza leitura especial se o bloco tiver erro
- this.contadorDeLeituraEspecial++;
- this.contadorDeCiclos += ConstanteDeTempo.leitura_especial;
- }
- }
- if (c.getBloco(numBloco).isSujo()) {
- //Contabilizar um WB
- this.contadorDeCiclos += ConstanteDeTempo.WB;
- this.contadorDeWB++;
- this.escritaSDRAM += 32;
- // System.err.println("fazer WB");
- }
- c.desalocaBloco(numBloco);
- }
- private void tratarErroNaRed(Requisicao req, int numBloco) {
- Conjunto c = this.conjuntos[req.conjunto];
- this.leituraEspecial(req.conjunto, c.getRR());
- c.getBloco(numBloco).setarComoInvalido();
- }
-
- private void contabilizaEscrita(Conjunto c, Requisicao req, int bloco){
- if(!req.read){
- if(c.getBloco(bloco).getErroDasPalavraDoBloco()[req.palavra]){
- this.escritaRedundancia++;
- }else{
- this.escritaCache++;
- }
- }
- }
-
- private void contabilizaLeitura(int conjunto,int numBloco, int palavra){
- boolean erro = this.conjuntos[conjunto].getBloco(numBloco).getErroFromPalavra(palavra);
- if(erro){
- this.leituraRedundancia++;
- }else{
- this.leituraCache++;
- }
- }
- private void requisicaoDeBlocoNoConjunto(Requisicao req) {
- //Se está nesse método,é porque deu miss
- Conjunto c = this.conjuntos[req.conjunto];
- boolean flagAlocaBloco = true;
- if (c.hasBlocoLivre()) { //USA RR
- // System.err.println("Vai usar RR. Vai para o bloco: "+c.getRR());
- if (c.getBloco(c.getRR()).isCachavel()) {
-
- this.leituraSDRAM +=32;
-
- if(req.read){
- this.contabilizaLeitura(req.conjunto, c.getRR(), req.palavra);
- }
-
- //Caso seja um bloco ocupado, precisa fazer verificar a necessidade de WB
- if (c.isBlocoOcupado(c.getRR())) {
- // System.err.println("O bloco já estava ocupado. Vai fazer WB");
- this.tratarWB(req, c.getRR()); //Aqui já contabiliza ciclos e WB
- }
- if (c.getBloco(c.getRR()).hasErrorInBloco()) { //Verifica se tem erro nas palavras do bloco
- // System.err.println("Tem erro no bloco");
- flagAlocaBloco = !this.trataBlocoComErro(req, c, c.getRR());//Contabiliza escrita na cache
- }else{
- this.escritaCache += 32;
- }
- if (flagAlocaBloco) {
- // System.err.println("Vai alocar o bloco");
- // System.err.println("");
- this.contabilizaEscrita(c,req,c.getRR());
-
- c.alocarBloco(req, c.getRR());
- } else {
- // System.err.println("ñ Vai alocar o bloco");
- // System.err.println("");
- this.contadorDeWBForcado++;
- this.escritaSDRAM += 32;
- //Não foi colocado em Cache pois tem erro na red
- if (req.read) {
- this.contadorDeCiclos += 1 + 1; //1 ciclo para devolver + 1 para acessar vetor de erros
- } else {
- this.contadorDeCiclos += ConstanteDeTempo.escrita_1_palavra_na_SDRAM;
- }
- this.tratarErroNaRed(req,c.getRR());
- //Aqui falta contabilizar algumas coisas (tempo se for write)
- }
- //Atualiza as variáves da política de substituição de bloco
- c.lru.atualizaLRU(c.getRR());
- c.atualizaRR();
- } else {
- this.ContadorIncachavel++;
-
-
- c.atualizaRR();
- // System.err.println("Incachavel");
- //Só contabiliza o custo da operação na memória principal
- if (req.read) {
- this.contadorDeCiclos += 1;
- this.leituraSDRAM += 1;
- } else {
- this.escritaSDRAM += 1;
- this.contadorDeCiclos += ConstanteDeTempo.escrita_1_palavra_na_SDRAM;
- }
- }
- } else {
- //Usa LRU
- // System.err.println("Vai usar LRU. Vai para o bloco: "+c.lru.getBlocoFromLru());
- int blocoSelecionado = c.lru.getBlocoFromLru();
- if (c.getBloco(blocoSelecionado).isCachavel()) {
-
- this.leituraSDRAM +=32;
- if(req.read){
- this.contabilizaLeitura(req.conjunto, blocoSelecionado, req.palavra);
- }
-
- if (c.getBloco(blocoSelecionado).hasErrorInBloco()) {
- // System.err.println("Tem erro no bloco");
- //Faz WB do bloco que foi selecionado para ser retirado da Cache
- this.tratarWB(req, blocoSelecionado); //Já contabiliza ciclos e WB
- //Escreve novo bloco na cache e os endereços com erro na red. Além disso, faz WBF e LE
- flagAlocaBloco = !this.trataBlocoComErro(req, c, blocoSelecionado); //Contabiliza escrita
- if (flagAlocaBloco) {
- // System.err.println("Vai alocar o bloco\n");
- // System.err.println("");
- this.contabilizaEscrita(c, req,blocoSelecionado);
- c.alocarBloco(req, c.getRR());
- } else {
- // System.err.println("ñ Vai alocar o bloco\n");
- // System.err.println("");
- //Não foi colocado em Cache pois tem erro na red
- this.contadorDeWBForcado++;
- this.tratarErroNaRed(req,blocoSelecionado);
- if (req.read) {
- this.contadorDeCiclos += 1;
- } else {
- this.contadorDeCiclos += ConstanteDeTempo.escrita_1_palavra_na_SDRAM;
- }
- }
- } else{ //Caso o bloco não tenha erro, tratar as usual
- this.escritaCache += 32;
- //Caso o Bloco esteja Sujo, precisa fazer WB
- if (c.getBlocos()[blocoSelecionado].isSujo()) {
- //Contabilizar WB
- this.tratarWB(req, blocoSelecionado); //Já contabiliza WB
- c.alocarBloco(req, blocoSelecionado);
- } else {//Caso precise só trocar o bloco, pois está limpo
- // Contabiliza nada aqui, pois o bloco tá limpo
- c.alocarBloco(req, blocoSelecionado);
- }
- }
- } else {
- //System.err.println("Incachavel");
- //Só contabiliza o custo da operação na memória principal
- this.ContadorIncachavel++;
- if(req.read){
- this.leituraSDRAM+=1;
- this.contadorDeCiclos += 1;
- }else{
- this.escritaSDRAM+=1;
- this.contadorDeCiclos += ConstanteDeTempo.escrita_1_palavra_na_SDRAM;
- }
- }
- //Atualiza politica de substituição LRU
- c.lru.atualizaLRU(blocoSelecionado);
- }
- }
- /**
- * Insere erro na memória cache
- * @param conjunto - Número do conjunto
- * @param bloco - Número do bloco
- * @param palavra - Número da palavra
- */
- public void inserirErro(int conjunto, int bloco, int palavra) {
- this.conjuntos[conjunto].getBlocos()[bloco].inserirErro(palavra);
- }
- private Conjunto[] getConjuntos() {
- return this.conjuntos;
- }
- private boolean isHit(Requisicao address) {
- return conjuntos[address.conjunto].verificaHit(address);
- }
- public Redundancia getRedundancia() {
- return this.redundancia;
- }
- @Override
- public String toString() {
- String s = "";
- Bloco[] b;
- int i = 0;
- for (Conjunto conjunto : conjuntos) {
- s += "Conjunto " + i + "\n";
- //s += conjunto;
- b = conjunto.getBlocos();
- int j = 0;
- for (Bloco bloco : b) {
- s += "Bloco " + j + "\n";
- s += bloco + "\n";
- j++;
- }
- s += "\n\n\n";
- i++;
- }
- return s; //To change body of generated methods, choose Tools | Templates.
- }
- }
|