📄 ubuf.c
字号:
#endif /* statistics ---------------------------------------------------------*/ if ((max_wr_coals > 0) && (ubufptr->max_wr_coals < req->size)) ubufptr->max_wr_coals = req->size; if ((max_rd_coals > 0) && (ubufptr->max_rd_coals < req->size)) ubufptr->max_rd_coals = req->size; n = i + num_coals; /* check if rest */ while ((n < ubufptr->entrysz) && /* of entry is empty */ (ubufptr->entries[0]->reqs[n] == NULL)) n++; if (n >= ubufptr->entrysz) /* if empty: shift */ { UBUFITEM *old; if (ubufptr->entries[0]->fence) ubufptr->cur_reads--; old = ubufptr->entries[0]; for (n = 1; n < ubufptr->num_entries; n++) /* shift all entries */ ubufptr->entries[n-1] = ubufptr->entries[n]; ubufptr->entries[ubufptr->num_entries-1] = old; /* clear old top entry */ ubufptr->num_entries--; StatrecUpdate(ubufptr->occ, ubufptr->num_entries, YS__Simtime); } else ubufptr->entries[0]->busy = 1; }}/*===========================================================================*//* determine maximum number of request that can be combined, beginning at *//* 'start'. The size of a combined request must be a power of two, and the *//* start address must be aligned to this size. Returns size of request. *//*===========================================================================*/int MaxCoalesce(UBUF *ubufptr, int start){ int align, max, n; if (ubufptr->entries[0]->reqs[start]->size < WD) return(0); /* count consecutive requests and sum up total request size -------------*/ for (n = start, max = 0; (n < ubufptr->entrysz) && (ubufptr->entries[0]->reqs[n] != NULL); max += ubufptr->entries[0]->reqs[n]->size / 4, n += ubufptr->entries[0]->reqs[n]->size / 4); /* reduce size of request until alignment is OK -------------------------*/ align = ubufptr->entrysz; while ((align > 1) && ((start % align) != 0)) align /= 2; /* reduce size further until less than or equal to uncached buffer size -*/ for (n = ubufptr->entrysz; n > max; n /= 2); max = n;#ifdef UBUF_TRACE for (n = 0; n < ubufptr->entrysz; n++) YS__logmsg(ubufptr->nodeid, "%s ", ubufptr->entries[0]->reqs[n] == NULL ? "_" : "X"); YS__logmsg(ubufptr->nodeid, " -> %i (%i %i)\n", max >= align ? align : max, align, max);#endif if (max >= align) return align; else return max;}/*=========================================================================*//* pending uncached buffer transaction is accepted by bus interface, and *//* ordering constraints are satisfied -> next request can be sent. *//*=========================================================================*/void UBuffer_confirm_transaction(REQ* req){ PID2UBUF(req->node, req->src_proc)->transaction_pending = 0;}/*===========================================================================*//* UBuffer_init: creates and initializes all UBuffer modules *//*===========================================================================*/void UBuffer_init(void){ int n, c, i; UBUF *ubufptr; char ubstr[40]; /*-------------------------------------------------------------------------*/ UBuffers = RSIM_CALLOC(UBUF*, ARCH_numnodes * ARCH_cpus); if (!UBuffers) YS__errmsg(0, "Malloc failed at %s:%i", __FILE__, __LINE__); /*-------------------------------------------------------------------------*/ for (n = 0; n < ARCH_numnodes; n++) for (c = 0; c < ARCH_cpus; c++) { ubufptr = RSIM_CALLOC(UBUF, 1); if (!ubufptr) YS__errmsg(n, "Malloc failed at %s:%i", __FILE__, __LINE__); PID2UBUF(n, c) = ubufptr; ubufptr->size = 4; ubufptr->entrysz = 8; ubufptr->combine = 1; ubufptr->flush = 1; get_parameter("ubufsize", &ubufptr->size, PARAM_INT); get_parameter("ubufflush", &ubufptr->flush, PARAM_INT); get_parameter("ubufentrysize", &ubufptr->entrysz, PARAM_INT); strcpy(ubstr, "comb"); get_parameter("ubuftype", ubstr, PARAM_STRING); if (strncasecmp(ubstr, "comb", 4) == 0) ubufptr->combine = 1; else if (strncasecmp(ubstr, "nocomb", 6) == 0) ubufptr->combine = 0; else { fprintf(stderr, "Unknown uncached buffer type %s\n", ubstr); exit(1); } /*---------------------------------------------------------------------*/ ubufptr->nodeid = n; ubufptr->procid = c; ubufptr->above = PID2L1D(n, c); ubufptr->below = PID2L2C(n, c); ubufptr->num_entries = 0; ubufptr->line_mask = ~(ubufptr->entrysz-1); ubufptr->entries = RSIM_CALLOC(UBUFITEM*, ubufptr->size); if (!ubufptr->entries) YS__errmsg(n, "Malloc failed at %s:%i", __FILE__, __LINE__); for (i = 0; i < ubufptr->size; i++) { ubufptr->entries[i] = RSIM_CALLOC(UBUFITEM, 1); if (ubufptr->entries[i] == NULL) YS__errmsg(n, "Malloc failed at %s:%i", __FILE__, __LINE__); ubufptr->entries[i]->reqs = RSIM_CALLOC(REQ*, ubufptr->entrysz); if (ubufptr->entries[i]->reqs == NULL) YS__errmsg(n, "Malloc failed at %s:%i", __FILE__, __LINE__); memset(ubufptr->entries[i]->reqs, 0, ubufptr->entrysz * sizeof(REQ*)); } ubufptr->cur_reads = 0; ubufptr->transaction_pending = 0; /*---------------------------------------------------------------------*/ ubufptr->occ = NewStatrec(n, "UBuf occupancy", INTERVAL, MEANS, HIST, ubufptr->size, 0, ubufptr->size); UBuffer_stat_clear(n, c); }}/*===========================================================================*//* UBuffer_Print_params(): Print uncached buffer configuration *//*===========================================================================*/void UBuffer_print_params(int nid, int pid){ UBUF *ubufptr = PID2UBUF(nid, pid); YS__statmsg(nid, "Uncached Buffer Configuration\n"); YS__statmsg(nid, " Entries: %d\t\tEntrysize: %d\n", ubufptr->size, ubufptr->entrysz); YS__statmsg(nid, " %s\t\tFlush at %i\n\n", ubufptr->combine ? "Combine" : "Don't Combine", ubufptr->flush); YS__statmsg(nid, "\n");} /*===========================================================================*//* UBuffer_stat_report: Reports statistics of a UBuffer module *//*===========================================================================*/ void UBuffer_stat_report(int nid, int pid){ UBUF *ubufptr = PID2UBUF(nid, pid); YS__statmsg(nid, "Uncached Buffer Statistics\n"); YS__statmsg(nid, " Stalls (Buffer Full) : %lld cycles\n", ubufptr->stall_ub_full); StatrecReport(nid, ubufptr->occ); if (ubufptr->num_writes) YS__statmsg(nid, " Total writes : %8lld\n", ubufptr->num_writes); if (ubufptr->num_wr_coals) YS__statmsg(nid, " Writes Coalesced: %8lld\tMax writes coalesced: %8lld bytes\n", ubufptr->num_wr_coals, ubufptr->max_wr_coals); if (ubufptr->num_reads) YS__statmsg(nid, " Total reads : %8lld\tRead Latency : %8.3f cycles\n", ubufptr->num_reads, ubufptr->read_latency / (double)ubufptr->num_reads); if (ubufptr->num_rd_coals) YS__statmsg(nid, " Reads Coalesced : %8lld\tMax reads coalesced : %8lld bytes\n", ubufptr->num_rd_coals, ubufptr->max_rd_coals); if (ubufptr->num_barriers) YS__statmsg(nid, " Memory Barriers : %8lld\teffective : %lld\n\n", ubufptr->num_barriers, ubufptr->num_barr_eff); YS__statmsg(nid, "\n");}/*===========================================================================*//* UBuffer_stat_set: set statistics for completed transaction *//*===========================================================================*/void UBuffer_stat_set(REQ *req){ UBUF *ubufptr = PID2UBUF(req->node, req->src_proc); if (req->prcr_req_type == READ) { ubufptr->num_reads++; ubufptr->read_latency += (YS__Simtime - req->issue_time); } if (req->prcr_req_type == WRITE) { ubufptr->num_writes++; }}/*===========================================================================*//* UBuffer_stat_clear: Resets statistics collection for a UBuffer module *//*===========================================================================*/ void UBuffer_stat_clear(int nid, int pid){ UBUF *ubufptr = PID2UBUF(nid, pid); StatrecReset(ubufptr->occ); ubufptr->stall_ub_full = 0; ubufptr->num_wr_coals = 0; ubufptr->max_wr_coals = 0; ubufptr->num_rd_coals = 0; ubufptr->max_rd_coals = 0; ubufptr->num_barriers = 0; ubufptr->num_barr_eff = 0; ubufptr->num_writes = 0; ubufptr->num_reads = 0; ubufptr->read_latency = 0.0;}/*===========================================================================*//* Dump exhaustive debugging information *//*===========================================================================*/void UBuffer_dump(int proc_id){ int nid = proc_id / ARCH_cpus; int n, m; UBUF *ubufptr = PID2UBUF(nid, proc_id % ARCH_cpus); YS__logmsg(nid, "\n====== UNCACHED BUFFER ======\n"); YS__logmsg(nid, "num_entries(%d), cur_reads(%d), transaction_pending(%d)\n", ubufptr->num_entries, ubufptr->cur_reads, ubufptr->transaction_pending); for (n = 0; n < ubufptr->num_entries; n++) { YS__logmsg(nid, "item[%i]: fence(%i), address(0x%x), type(%s), busy(%s)\n", n, ubufptr->entries[n]->fence, ubufptr->entries[n]->address, ReqName[ubufptr->entries[n]->type], ubufptr->entries[n]->busy); for (m = 0; m < ubufptr->entrysz; m++) { if (ubufptr->entries[n]->reqs[m] == NULL) continue; Cache_req_dump(ubufptr->entries[n]->reqs[m], 0x11, nid); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -