void cmu_bdd_stats(cmu_bdd_manager bddm, FILE *fp) { long i; long ue, ce, cs, mem; SIZE_T alloc; assoc_list q; ue=bddm->unique_table.entries; ce=bddm->op_cache.entries; cs=bddm->op_cache.size; mem=0; for (i=0; i < bddm->vars; ++i) { mem+=sizeof(struct var_table_); mem+=bddm->unique_table.tables[i]->size*sizeof(bdd); } mem=ue*sizeof(struct bdd_); mem+=cs*sizeof(struct cache_bin_)+ce*sizeof(struct cache_entry_); mem+=bddm->maxvars*(sizeof(bdd_index_type)+sizeof(bdd_indexindex_type)+sizeof(bdd)+sizeof(var_table)); for (q=bddm->assocs, i=1; q; q=q->next, ++i); mem+=i*bddm->maxvars*sizeof(bdd); if ((alloc=mem_allocation())) /* mem_allocation may be meaningless depending on mem library. */ fprintf(fp, "Memory manager bytes allocated: %ld\n", (long)alloc); fprintf(fp, "Approximate bytes used: %ld\n", mem); fprintf(fp, "Number of nodes: %ld\n", ue); if (bddm->unique_table.node_limit) fprintf(fp, "Node limit: %ld\n", bddm->unique_table.node_limit); else fprintf(fp, "Node limit: ---\n"); fprintf(fp, "Overflow: %s\n", bddm->overflow ? "yes" : "no"); fprintf(fp, "Approximate bytes per node: %-.2f\n", ((double)mem)/ue); fprintf(fp, "Cache entries: %ld\n", ce); fprintf(fp, "Cache size: %ld\n", 2*cs); fprintf(fp, "Cache load factor: %-.2f\n", ((double)ce)/(2*cs)); fprintf(fp, "Cache look ups: %ld\n", bddm->op_cache.lookups); fprintf(fp, "Cache hits: %ld\n", bddm->op_cache.hits); if (bddm->op_cache.lookups) fprintf(fp, "Cache hit rate: %-.2f\n", ((double)(bddm->op_cache.hits))/bddm->op_cache.lookups); else fprintf(fp, "Cache hit rate: ---\n"); fprintf(fp, "Cache insertions: %ld\n", bddm->op_cache.inserts); fprintf(fp, "Cache collisions: %ld\n", bddm->op_cache.collisions); fprintf(fp, "Number of variables: %ld\n", bddm->vars); fprintf(fp, "Number of variable associations: %ld\n", i); fprintf(fp, "Number of garbage collections: %ld\n", bddm->unique_table.gcs); fprintf(fp, "Number of nodes garbage collected: %ld\n", bddm->unique_table.freed); fprintf(fp, "Number of find operations: %ld\n", bddm->unique_table.finds); }
void *workload_replayer(void *arg) { unsigned int tid = 0; readLine req; long long trace_sTime = -1; long long trace_wTime = 0; long long gio_sTime = 0; long long gio_wTime = 0; struct timeval now; int fd; char *buf; size_t ret; unsigned long mSize; unsigned long mAddr; OPERATION_TYPE op; desc = (wg_env *)arg; if( (fd = open(desc->file_path, O_CREAT|O_RDWR|O_DIRECT, 0666)) == -1 ){ //if( (fd = open(desc->file_path, O_CREAT|O_RDWR, 0666)) == -1){ PRINT("Error on opening the init_file of workload generator, file:%s, line:%d, fd=%d\n", __func__, __LINE__, fd); exit(1); } #if !defined(BLOCKING_IO) aio_initialize(desc->max_queue_depth); #endif mem_allocation(desc, &buf, REPLAYER_MAX_FILE_SIZE); if (NULL == buf) { PRINT("Error on memory allocation, file:%s, line:%d\n", __func__, __LINE__); exit(1); } while(1){ //Dequeueing req = de_queue(); //If a request is successfully dequeued. if(strcmp(req.rwbs, "EMPTY") != 0){ mSize = select_size(req.size); mAddr = select_start_addr(req.sSector); fill_data(desc, buf, mSize); //Calculate wait time based on trace log if(trace_sTime == -1){ get_start_time(&trace_sTime, &gio_sTime); } trace_wTime = MICRO_SECOND(req.sTime) - trace_sTime; if(trace_wTime < 0){ PRINT("trace_wTime : %lli\n", trace_wTime); PRINT("Issue time must be ordered. Check the issue time in trace file"); exit(1); } //Caculate how much time should wait get_current_time(&now); gio_wTime = TIME_VALUE(&now) - gio_sTime; PRINT("TIMEDEBUG trace_wTime:%10lli \tgio_wTime:%10lli\n", trace_wTime, gio_wTime); //If we need to wait if(trace_wTime > gio_wTime){ PRINT("WAITING ....%lli us\n", trace_wTime - gio_wTime); usec_sleep(trace_wTime - gio_wTime); } op = strstr(req.rwbs,"R")!=NULL? WG_READ : WG_WRITE; #if defined(BLOCKING_IO) if(op == WG_READ){ //PRINT("R\n"); ret = pread(fd, buf , (size_t)mSize, mAddr); }else{ //PRINT("W\n"); ret = pwrite(fd, buf , (size_t)mSize, mAddr); fsync(fd); } if (ret != mSize) { PRINT("Error on file I/O (error# : %zu), file:%s, line:%d\n", ret, __func__, __LINE__); break; } #else ret = aio_enqueue(fd, buf, mSize, mAddr, op); if (ret != 1) { PRINT("Error on file I/O (error# : %zu), file:%s, line:%d\n", ret, __func__, __LINE__); break; } #endif //BLOCKING_IO #if 0 PRINT("DEQUEUED REQ tid:%u sTime:%lf rwbs:%s Addr:%12li \t Size:%12lu\n\n", tid, req.sTime, req.rwbs, mAddr, mSize); #endif } if( get_queue_status() == 1 ){ PRINT("END OF REPLAYER\n"); break; } } pthread_mutex_destroy(&thr_mutex); }