Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef _SIM_H_
- #define _SIM_H_
- #include <stdint.h>
- #include <math.h>
- #include <stdio.h>
- #include <stdlib.h>
- struct cache{
- uint32_t assoc; /* associatividade, 1 para map. direto */
- uint32_t block; /* número de bytes por bloco */
- uint32_t num_blocks; /* número de blocos por conjunto */
- uint32_t lat; /* latência de acesso em ciclos */
- };
- struct stats{
- unsigned long *hits; /* vetor para cada nível de cache */
- unsigned long *misses; /* idem */
- unsigned long cycles; /* número total de ciclos da simulação */
- };
- /** Recebe um traço de endereços de memória acessados e simula hierarquia de memória
- * @param configs vetor de configurações de caches
- * @param num_configs número de níveis de cache
- * @param mem_lat latência em ciclos de acesso à memória
- * @param filename nome do arquivo de traço (ou null)
- * @param stream stream com traço (se filename for null)
- * @return estatísticas de simulação
- */
- struct stats * sim(struct cache * configs, int num_configs,
- uint32_t mem_lat, char * filename, char * stream);
- void setValues(uint32_t* tag, uint32_t* index, uint32_t size,struct cache * configs);
- void getValues(uint32_t*tag,uint32_t*index,uint32_t tagsize,uint32_t indexsize, uint32_t end);
- int _hash(char * str, int num_blocks, int assoc);
- int cacheSize(int assoc, int num_blocks, int block);
- void startStats(struct stats * sim);
- void LRUstart(uint32_t * Cache, uint32_t size);
- int dirMapped(uint32_t * Cache, int tag, int pos, int cycles,char mode,int extra);
- int assocMapped(uint32_t * Cache, int tag, int pos, int cycles, char mode,int extra, struct cache * configs);
- int getBlockPos(int index,int num_blocks);
- int acessCache(struct cache * config,struct stats sim,int * Cache, uint32_t end,int num_configs, uint32_t mem_lat,char mode);
- uint32_t hex2int(char *hex);
- /* TAG - BLOCK INDEX - OFFSET */
- int main(){
- //testa so mem
- /*
- char * trace = "R 12345678\nW 90ABCDEF\n";
- struct stats * res = sim(NULL, 0, 10, NULL, trace);
- */
- //testa l1
- //char * trace = "R 12345678\nW 90ABCDEF\n";
- struct cache mycache = {1, 4, 2, 1};
- //struct stats * res = sim(&mycache, 1, 10, NULL, trace);
- /*char * filename = "filename";
- char * trace = "R 12345678\nR 12345678\n";
- struct stats * res = sim(&mycache, 1, 10, NULL, trace);
- */
- struct cache mycache2 = {2, 8, 4, 1};
- char * trace3 = "R 12345678\nW 90ABCDEF\nW 00000410\nW 00000324\nW 000003ec\nW 00000410\n";
- struct stats * res = sim(&mycache2, 1, 10, NULL, trace3);
- return 0;
- }
- struct stats * sim(struct cache * configs, int num_configs, uint32_t mem_lat, char * filename, char * stream){
- struct stats *sim = malloc(sizeof(struct stats));
- FILE *fp = NULL;// = fopen("C:\\Users\\Laster\\Documents\\Standard\\Estudos\\filename.txt","r");
- int size = 0;
- uint32_t end, i = 0, bit = 0, full = 0,tag,indexsize,index, tagsize, pos,extra = 0;
- char *p = stream, str[11], *q, str1[11], str2[11];
- printf("test\n");
- printf("test\n");
- printf("test\n");
- if(configs != NULL){
- size = cacheSize(configs->assoc,configs->num_blocks,configs->block);
- setValues(&tagsize,&indexsize,size, configs);
- }
- startStats(sim);
- uint32_t Cache[configs->num_blocks];
- if(fp != NULL) // TEM ARQUIVO
- {
- while(fscanf(fp,"%[^\n]\n",str) != EOF)
- {
- printf("%s\n", str);
- }
- return NULL;
- }
- else // USAR STREAM
- {
- while( *p != '\0'){
- while(*p != '\n' && *p != '\0'){ //pega o endereço em string
- str[i] = *p;
- i++;p++;
- }
- p++;
- str[i] = '\0';
- q = str + 2;
- end = hex2int(str);
- i = 0;
- //getValues(&tag,&index,tagsize,indexsize,end);
- if(acessCache(configs,*sim,&Cache,end,num_configs,mem_lat,str[0])){}
- /*
- if(num_configs == 0){ //ACESSO DIRETO A MEMORIA
- (*sim).cycles += mem_lat;
- }
- else if(num_configs == 1){ //ACESSO L1
- //end = _hash(str1,configs->num_blocks,configs->assoc);
- pos = getBlockPos(index,configs->num_blocks);
- printf("\npos=%d\n", pos);
- if(configs->assoc == 1){ //mapeando direto
- if(dirMapped(Cache,tag,pos,sim->cycles,str[0],extra)){ //hit
- sim->cycles += configs->lat;
- *(*sim).hits += 1;
- }
- else{//miss
- if(extra == 1){(*sim).cycles += mem_lat;} //if it was a miss in a writtenblock then writeback policy
- (*sim).cycles += 1;
- (*sim).cycles += mem_lat;
- *(*sim).misses += 1;
- }
- extra = 0;
- }
- else if(configs->assoc == configs->num_blocks){ //assoaciatividade completa
- }
- else{ //associativo
- if(assocMapped(Cache,tag,pos,sim->cycles,str[0],extra,configs)){
- sim->cycles += configs->lat;
- *(*sim).hits += 1;
- }
- else{//miss
- if(extra == 1){(*sim).cycles += mem_lat;} //if it was a miss in a writtenblock then writeback policy
- (*sim).cycles += 1;
- (*sim).cycles += mem_lat;
- *(*sim).misses += 1;
- }
- }
- }
- else{ //ACESSO l2
- }*/
- }
- }
- return sim;
- }
- int assocMapped(uint32_t * Cache, int tag, int pos, int cycles, char mode,int extra, struct cache * configs){
- uint32_t tTag, timer = cycles, V, D, aux, i, LRUpos = cycles;
- for(i=0;i<configs->assoc;i++){ //laço para encontrar um bloco vazio
- V = Cache[pos] >> 31;
- D = Cache[pos] << 1 >> 31;
- aux = tag; aux <<= 10;
- timer = cycles;
- aux = aux | timer; //aux OR timer, coloca tag e timer da LRU nos bits
- if(V == 0){ //checks if its not inicialized, else verifies if its a hit
- V = 1;
- if(mode == 'R'){
- Cache[pos] = 1;
- Cache[pos] = Cache[pos] << 31;
- }
- else{
- Cache[pos] = 3;
- Cache[pos] = Cache[pos] << 30;
- }
- Cache[pos] = Cache[pos] | aux; // V - D - tag - LRU
- printf("%d", Cache[pos]);
- return 0; //return miss
- }
- else{
- tTag = Cache[pos] << 2; tTag = tTag >> 12;
- if(tag == tTag){ // HIT
- if(mode == 'R'){
- Cache[pos] = 1; Cache[pos] = Cache[pos] << 31;
- Cache[pos] = Cache[pos] | aux; // V - D - tag - LRU
- }
- else{
- Cache[pos] = 3; Cache[pos] = Cache[pos] << 30;
- Cache[pos] = Cache[pos] | aux; // V - D - tag - LRU
- }
- Cache[pos] = Cache[pos] >> 10; //Limpa LRU
- Cache[pos] = Cache[pos] << 10;
- Cache[pos] = Cache[pos] | cycles; //atualiza LRU
- return 1; //return hit
- }
- if(LRUpos < timer){ //finds the least recently used block in case theres no free block
- LRUpos = pos;
- }
- }
- pos += configs->num_blocks;
- }
- //at this point theres no empty block, and no hits, so we use LRU policy
- pos = LRUpos;
- D = Cache[pos] << 1 >> 31;
- V = Cache[pos] >> 31;
- aux = tag; aux <<= 10;
- timer = cycles;
- aux = aux | timer; //aux OR timer, coloca tag e timer da LRU nos bits
- if(D == 1){ extra = 1; }
- if(mode == 'R'){
- Cache[pos] = 1; Cache[pos] = Cache[pos] << 31;
- Cache[pos] = Cache[pos] | aux; // V - D - tag - LRU
- }
- else{
- Cache[pos] = 3; Cache[pos] = Cache[pos] << 30;
- Cache[pos] = Cache[pos] | aux; // V - D - tag - LRU
- }
- Cache[pos] = Cache[pos] >> 10; //Limpa LRU
- Cache[pos] = Cache[pos] << 10;
- Cache[pos] = Cache[pos] | cycles; //atualiza LRU
- return 0;
- }
- int dirMapped(uint32_t * Cache, int tag, int pos, int cycles, char mode,int extra){
- uint32_t tTag, timer, V, D, aux;
- D = Cache[pos] << 1 >> 31;
- V = Cache[pos] >> 31;
- aux = tag; aux <<= 10;
- timer = cycles;
- aux = aux | timer; //aux OR timer, coloca tag e timer da LRU nos bits
- if(V == 0){ //bloco nao utilizado antes, logo miss
- V = 1;
- if(mode == 'R')
- Cache[pos] = 1; //Cache[pos] = Cache[pos] << 30;
- else
- Cache[pos] = 3; Cache[pos] = Cache[pos] << 30;
- Cache[pos] = Cache[pos] | aux; // V - D - tag - LRU
- return 0; //return miss
- }
- else{ //
- timer = Cache[pos] << 22; timer = timer >> 22;
- tTag = Cache[pos] << 2; tTag = tTag >> 12;
- if(tag == tTag){ // HIT
- if(mode == 'R'){
- Cache[pos] = 1; Cache[pos] = Cache[pos] << 31;
- Cache[pos] = Cache[pos] | aux; // V - D - tag - LRU
- }
- else{
- Cache[pos] = 3; Cache[pos] = Cache[pos] << 30;
- Cache[pos] = Cache[pos] | aux; // V - D - tag - LRU
- }
- Cache[pos] = Cache[pos] >> 10; //Limpa LRU
- Cache[pos] = Cache[pos] << 10;
- Cache[pos] = Cache[pos] | cycles; //atualiza LRU
- return 1; //return hit
- }
- else{ //MISS
- if(D == 1){ extra = 1; }
- if(mode == 'R'){
- Cache[pos] = 1; Cache[pos] = Cache[pos] << 31;
- Cache[pos] = Cache[pos] | aux; // V - D - tag - LRU
- }
- else{
- Cache[pos] = 3; Cache[pos] = Cache[pos] << 30;
- Cache[pos] = Cache[pos] | aux; // V - D - tag - LRU
- }
- Cache[pos] = Cache[pos] >> 10; //Limpa LRU
- Cache[pos] = Cache[pos] << 10;
- Cache[pos] = Cache[pos] | cycles; //atualiza LRU
- }
- }
- return 0;
- }
- //this function is taken from: https://stackoverflow.com/questions/10156409/convert-hex-string-char-to-int
- //
- uint32_t hex2int(char *hex) {
- uint32_t val = 0;
- while (*hex) {
- // get current character then increment
- uint8_t byte = *hex++;
- // transform hex character to the 4bit equivalent number, using the ascii table indexes
- if (byte >= '0' && byte <= '9') byte = byte - '0';
- else if (byte >= 'a' && byte <='f') byte = byte - 'a' + 10;
- else if (byte >= 'A' && byte <='F') byte = byte - 'A' + 10;
- // shift 4 to make space for new digit, and add the 4 bits of the new digit
- val = (val << 4) | (byte & 0xF);
- }
- return val;
- }
- void getValues(uint32_t*tag,uint32_t*index,uint32_t tagsize,uint32_t indexsize,uint32_t end){
- *tag = end >> (32-tagsize); //32 - (tagsize + indexsize) -> calculo do OFFSET
- *index = end << tagsize >> 32 - (tagsize + indexsize) + tagsize;
- return;
- }
- int getBlockPos(int index,int num_blocks){
- return index % num_blocks;
- }
- void setValues(uint32_t* tag, uint32_t* index, uint32_t size,struct cache * configs){
- int offset = (int) log2((double)configs->block);
- *index = (int) log2((double)configs->num_blocks);
- *tag = 32 - (*index + offset);
- }
- /*
- setStrings(str1,str2,stream);
- void setStrings(char * str1, char * str2, char * stream){ //Funcao para separar os endereços de entrada
- int i; char *p;
- p = stream;
- for(i=0; *p != '\n'; p++,i++){
- str1[i] = *p;
- }
- p = stream+11;
- for(i=0; *p != '\n'; p++,i++){
- str2[i] = *p;
- }
- str1[i] = '\0';
- str2[i] = '\0';
- return;
- }*/
- int _hash(char * str, int num_blocks, int assoc){
- int i, res, target_block;
- char *p, op[3];
- char q = str + 7;
- for(i=0;i<3;i++,p++){
- op[i] = *p;
- }
- res = (int) strtol(op, NULL, 16); //converts string to long int, third arg selects base.
- target_block = res % assoc;
- res = res % num_blocks;
- if(assoc == 1)
- return res;
- else
- return target_block;
- }
- int cacheSize(int assoc, int num_blocks, int block){
- printf("here");
- return assoc * (4*block) * num_blocks;
- }
- void startStats(struct stats * sim){
- //sim->cycles = malloc(sizeof(unsigned long));
- (*sim).hits = malloc(sizeof(unsigned long));
- (*sim).misses = malloc(sizeof(unsigned long));
- (*sim).cycles = 0;
- *(*sim).hits = 0;
- *(*sim).misses = 0;
- return;
- }
- void LRUstart(uint32_t * Cache, uint32_t size){
- uint32_t i;
- for(i = 0 ; i<size ; i++){
- Cache[i] = i;
- }
- }
- int acessCache(struct cache * config,struct stats sim,int * Cache, uint32_t end,int num_configs, uint32_t mem_lat,char mode){
- uint32_t tag,index,tagsize,indexsize,size,pos,extra;
- setValues(&tagsize,&indexsize,size, configs);
- getValues(&tag,&index,tagsize,indexsize,end);
- if(num_configs == 0){ //ACESSO DIRETO A MEMORIA
- (*sim).cycles += mem_lat;
- }
- else if(num_configs == 1){ //ACESSO L1
- //end = _hash(str1,configs->num_blocks,configs->assoc);
- pos = getBlockPos(index,configs->num_blocks);
- printf("\npos=%d\n", pos);
- if(configs->assoc == 1){ //mapeando direto
- if(dirMapped(Cache,tag,pos,sim->cycles,mode,extra)){ //hit
- sim->cycles += configs->lat;
- *(*sim).hits += 1;
- }
- else{//miss
- if(extra == 1){(*sim).cycles += mem_lat;} //if it was a miss in a writtenblock then writeback policy
- (*sim).cycles += 1;
- (*sim).cycles += mem_lat;
- *(*sim).misses += 1;
- }
- extra = 0;
- }
- else if(configs->assoc == configs->num_blocks){ //assoaciatividade completa
- }
- else{ //associativo
- if(assocMapped(Cache,tag,pos,sim->cycles,mode,extra,configs)){
- sim->cycles += configs->lat;
- *(*sim).hits += 1;
- }
- else{//miss
- if(extra == 1){(*sim).cycles += mem_lat;} //if it was a miss in a writtenblock then writeback policy
- (*sim).cycles += 1;
- (*sim).cycles += mem_lat;
- *(*sim).misses += 1;
- }
- }
- }
- #endif // _SIM_H_
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement