Ir ao conteúdo

Posts recomendados

Postado

O esboço da cache esta pronto, então comecei a implementar as politicas de substituição

comecei pela LRU que estou tendo dificuldades, fiz a cache como uma matriz, se o endereço não existe na cache acho a posição adequada e coloco o endereço correto nela, mas na matriz esta aparecendo um monte de lixo depois do endereço

 

#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <conio.h>

#define tamanhoTeste 100
#define tamanhoOficial 51200

typedef struct informacao {
	int bitsPalavra;
	int numeroLinhasConjunto;
	int tamanhoCache;
	int bitsTamanhaoLinha;
	int bitsTamanhoCache;
	int bitsConjunto;
	int bitsRotulo;
	int politicaEscrita;
	int politicaSubstituicao;
} INFO;

typedef struct estatisticas {
	int hit;
	int miss;
	int leiturasCache;
	int escritasCache;
} ESTAT;

INFO lerInfomacao() {
	int aux, aux2;
	INFO info;

	info.tamanhoCache = 0;
	info.bitsTamanhoCache = 0;
	info.bitsPalavra = 0;
	info.bitsTamanhaoLinha = 0;
	info.numeroLinhasConjunto = 0;
	info.bitsConjunto = 0;
	info.bitsRotulo = 0;
	info.politicaEscrita = 0;
	info.politicaSubstituicao = 0;

	printf("Digite o tamanho da memoria cache (KB): ");
	scanf("%d", &info.tamanhoCache);
	fflush(stdin);

	aux = info.tamanhoCache;
	while (aux > 1) {
		aux /= 2;
		info.bitsTamanhoCache++;
	}
	info.bitsTamanhoCache += 10;

	printf("Digite o tamanho da linha (BYTES): ");
	scanf("%d", &aux);
	fflush(stdin);

	while (aux > 1) {
		aux /= 2;
		info.bitsPalavra++;
	}

	info.bitsTamanhaoLinha = info.bitsTamanhoCache - info.bitsPalavra;

	printf("Digite o numero de linhas por conjunto: ");
	scanf("%d", &info.numeroLinhasConjunto);
	fflush(stdin);

	aux = (pow(2, info.bitsTamanhaoLinha));
	aux2 = aux / info.numeroLinhasConjunto;

	while (aux2 > 1) {
		aux2 /= 2;
		info.bitsConjunto++;
	}

	info.bitsRotulo = 32 - (info.bitsConjunto + info.bitsPalavra);

	do {
		printf(
				"\n1-Write-through\n2-Write-back\nDigite qual politica de escrita deseja utilizar: ");
		scanf("%d", &info.politicaEscrita);
		fflush(stdin);
		if (info.politicaEscrita < 1 || info.politicaEscrita > 2)
			printf("Opção invalida!");
	} while (info.politicaEscrita < 1 || info.politicaEscrita > 2);

	do {
		printf(
				"\n1-LFU (Least Frequently Used)\n2-LRU (Least Recently Used)\n3-Aleatória\nDigite qual politica de escrita deseja utilizar: ");
		scanf("%d", &info.politicaSubstituicao);
		fflush(stdin);
		if (info.politicaSubstituicao < 1 || info.politicaSubstituicao > 3)
			printf("Opção invalida!");
	} while (info.politicaSubstituicao < 1 || info.politicaSubstituicao > 3);

	return info;
}

char *hexBin(INFO info, int tam, char enderecoHexaTeste[10]) {
	char nibble[32];
	static char enderecoBinarioTeste[32];
	int k;

	strcpy(enderecoBinarioTeste, "");

	for (k = 0; k < 8; k++) {
		strcpy(nibble, "");
		switch (enderecoHexaTeste[k]) {
		case '0':
			strcpy(nibble, "0000");
			break;
		case '1':
			strcpy(nibble, "0001");
			break;
		case '2':
			strcpy(nibble, "0010");
			break;
		case '3':
			strcpy(nibble, "0011");
			break;
		case '4':
			strcpy(nibble, "0100");
			break;
		case '5':
			strcpy(nibble, "0101");
			break;
		case '6':
			strcpy(nibble, "0110");
			break;
		case '7':
			strcpy(nibble, "0111");
			break;
		case '8':
			strcpy(nibble, "1000");
			break;
		case '9':
			strcpy(nibble, "1001");
			break;
		case 'a':
			strcpy(nibble, "1010");
			break;
		case 'b':
			strcpy(nibble, "1011");
			break;
		case 'c':
			strcpy(nibble, "1100");
			break;
		case 'd':
			strcpy(nibble, "1101");
			break;
		case 'e':
			strcpy(nibble, "1110");
			break;
		case 'f':
			strcpy(nibble, "1111");
			break;
		}

		strcat(enderecoBinarioTeste, nibble);
	}

	enderecoBinarioTeste[32] = '\0';

	return enderecoBinarioTeste;
}

void separaEndereco(char enderecoBinario[30], INFO info,
		char palavra[info.bitsPalavra], char conjunto[info.bitsConjunto],
		char rotulo[info.bitsRotulo]) {

	strcpy(rotulo, "");
	strcpy(conjunto, "");
	strcpy(palavra, "");

	int i, j = 0, k = 1;

	for (i = 0; i < 32; i++) {
		if (k == 1) {
			if (j < info.bitsRotulo && k == 1) {
				rotulo[j] = enderecoBinario[i];
				j++;
			} else {
				rotulo[j] = '\0';
				j = 0;
				k = 2;
			}
		}
		if (k == 2) {
			if (j < info.bitsConjunto && k == 2) {
				conjunto[j] = enderecoBinario[i];
				j++;
			} else {
				conjunto[j] = '\0';
				j = 0;
				k = 3;
			}
		}
		if (k == 3) {
			if (j < info.bitsPalavra && k == 3) {
				palavra[j] = enderecoBinario[i];
				j++;
			} else {
				palavra[j] = '\0';
				j = 0;
				k = 0;
			}
		}
	}
	palavra[info.bitsPalavra] = '\0';

}

int binDec(int bits, char coisa[bits]) {
	int coi = 0, i = bits - 1, j = 0;
	while (j < bits) {
		if (coisa[j] == '1') {
			coi += pow(2, i);
		}
		i--;
		j++;
	}
	return coi;
}

int inicioConjuntoCache(INFO info, char conjunto[info.bitsConjunto]) {
	int conj = binDec(info.bitsConjunto, conjunto);
	int linhaCacheAcessada = conj * info.numeroLinhasConjunto;

	return linhaCacheAcessada;
}

void politicaLRU(INFO info, int linhaCacheAcessada, int tamanhoC, char cache[tamanhoC][32], char enderecoBinarioTeste[30],	int LRU[tamanhoC]) {
	int i = linhaCacheAcessada, pos, achou = 0;
	int menor = LRU[linhaCacheAcessada];

	while (i < (linhaCacheAcessada + info.numeroLinhasConjunto) && achou == 0) {
		if (strcmp(cache[i], "")==0) {
			strcpy(cache[i], enderecoBinarioTeste);
			achou=1;
		}else
			i++;
		//if(LRU[i]<menor){
			//menor=LRU[i];
			//pos=i;
		//}
		//i++;
	}
	cache[i][32]='\0';
	//strcpy(cache[i], enderecoBinarioTeste);
	//strcpy(cache[pos], enderecoBinarioTeste);

	/*for (i = linhaCacheAcessada;
			i < linhaCacheAcessada + info.numeroLinhasConjunto; i++) {
		if (strcmp(cache[i], "#") != 0) {
			if (LRU[i] < menor) {
				menor = LRU[i];
				pos = i;
			}
		} else {
			strcpy(cache[i], enderecoBinarioTeste);
			pos = -1;
			break;
		}
	}
	if (pos != -1) {
		strcpy(cache[pos], enderecoBinarioTeste);
	}*/
}

void verificaLinhaRotuloCache(INFO info, int linhaCacheAcessada, int tamanhoC,
		char cache[tamanhoC][32], char palavraTeste[info.bitsPalavra],
		char conjuntoTeste[info.bitsConjunto],
		char rotuloTeste[info.bitsRotulo], int LRU[tamanhoC], int *acerto,
		char enderecoBinarioTeste[30]) {
	int i;

	char rotuloC[info.bitsRotulo];
	char conjuntoC[info.bitsConjunto];
	char palavraC[info.bitsPalavra];

	*acerto = 0;

	for (i = linhaCacheAcessada;
			i < linhaCacheAcessada + info.numeroLinhasConjunto; i++) {
		separaEndereco(cache[i], info, palavraC, conjuntoC, rotuloC);
		if (strcmp(rotuloC, rotuloTeste) == 0) {
			*acerto = 1;
		} else {
			LRU[i]++;
		}

	}
	if (*acerto == 0) {
		if (info.politicaSubstituicao == 2) {
			politicaLRU(info, linhaCacheAcessada, tamanhoC, cache,
					enderecoBinarioTeste, LRU);
		}
	}
	/*while (i < i + numeroLinhasConjunto && achou == 0 && i < tamanhoC) {
	 if(strcmp())

	 printf("RotuloC: %s Rotulo MP: %s\n",rotuloC, rotulo);

	 if (strcmp(rotuloC, rotulo) == 0)
	 achou = 1;
	 else {
	 LRU[i]++;
	 i++;
	 }
	 }

	 if (achou == 1) {
	 hit++;
	 } else {
	 miss++;
	 if (politicaSubstituicao == 2 && linhaCacheAcessada<tamanhoC) {
	 substituiLRU(tamanhoC, cache, numeroLinhasConjunto, enderecoBinario,
	 linhaCacheAcessada, LRU);
	 }
	 }*/

}

void leArquivo(INFO info) {
	int op;
	int tam;

	FILE *f;

	do {
		printf(
				"\n1-Teste.cache\n2-Oficial.cache\nEscolha qual arquivo deseja usar: ");
		scanf("%d", &op);
		fflush(stdin);
		if (op < 1 || op > 2)
			printf("Opção invalida!\n");
	} while (op < 1 || op > 2);

	switch (op) {
	case 1:
		tam = tamanhoTeste;
		f = fopen("teste.cache", "r");
		break;
	case 2:
		tam = tamanhoOficial;
		f = fopen("oficial.cache", "r");
		break;
	}

	char enderecoHexaTeste[tam][10], tipoOperacaoTeste[tam][10], dado[10];
	int i, k = 0, j = 0;

	for (i = 0; i < (tam * 2); i++) {
		fgets(dado, sizeof(dado), f);

		if (i % 2 == 0) {
			strcpy(enderecoHexaTeste[k], dado);
			k++;
		} else {
			strcpy(tipoOperacaoTeste[j], dado);
			j++;
		}
	}

	fclose(f);

	char palavraTeste[info.bitsPalavra];
	char conjuntoTeste[info.bitsConjunto];
	char rotuloTeste[info.bitsRotulo];
	char *enderecoBinarioTeste;

	int tamanhoC = (pow(2, info.bitsConjunto) * info.numeroLinhasConjunto);
	char cache[tamanhoC][32];
	int LRU[tamanhoC];

	int linhaCacheAcessada;

	int acerto;

	ESTAT estat;
	estat.hit = 0;
	estat.miss = 0;

	for (i = 0; i < tamanhoC; i++) {
		LRU[i] = 0;
	}

	for (i = 0; i < tamanhoC; i++) {
		strcpy(cache[i], "");
	}

	for (i = 0; i < tam; i++) {
		enderecoBinarioTeste = hexBin(info, tam, enderecoHexaTeste[i]);
		separaEndereco(enderecoBinarioTeste, info, palavraTeste, conjuntoTeste,	rotuloTeste);
		linhaCacheAcessada = inicioConjuntoCache(info, conjuntoTeste);
		verificaLinhaRotuloCache(info, linhaCacheAcessada, tamanhoC, cache,	palavraTeste, conjuntoTeste, rotuloTeste, LRU, &acerto,	enderecoBinarioTeste);

		if (acerto == 1) {
			estat.hit++;
		} else {
			estat.miss++;
		}

		//printf("endB: %s   R: %s   C: %s  P: %s  lA: %d\n", enderecoBinarioTeste,
		//		rotuloTeste, conjuntoTeste, palavraTeste, linhaCacheAcessada);
	}

	for (i = 0; i < tamanhoC; i++) {
		printf("EndC: %s\n", cache[i]);
	}

	printf("H: %d M:%d\n", estat.hit, estat.miss);

}

int main(void) {
	setbuf(stdout, NULL);

	INFO info;

	info = lerInfomacao();

	leArquivo(info);

	return EXIT_SUCCESS;
}

os dados que eu uso para testar são tamanho cache 8, tamanho linha 16, linha por conjunto 2

o arquivo de endereços usado é esse (para poder posta-lo tirei a extensão .cache)

 

capture-20170619-104640.png

cache.txt

  • Curtir 1
Postado

LOL, consegui implementar corretamente o LRU

por alguma razão desconhecida a logica que eu botei como comentário não funciona

                    separaEndereco(tamanhoC, cache, info, palavraC, conjuntoC,	rotuloC, i);
					int r1, r2;
					//ok=0;
					//for(l=0;l<32;l++){
					//	if(rotuloC[i][l]==rotuloTeste[j][l]){
					//		ok++;
					//	}
					//}
					r1=binDec(info.bitsRotulo, tam, rotuloTeste, j);
					r2=binDec(info.bitsRotulo, tamanhoC, rotuloC, i);
					cont++;
					//if(ok==info.bitsRotulo){
					if(r1==r2){
						foi=1;
						*acerto=1;
					}

 

  • 5 meses depois...

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...