⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpcache.c

📁 体系机构仿真
💻 C
📖 第 1 页 / 共 3 页
字号:
		    SET_L1_STATE (pid, L1_line, MODIFIED);		    SET_L2_STATE (pid, L2_line, MODIFIED_ABOVE);		}		break;	}    }    else /* no tag match, _or_ invalid state with tag match */    {	/* no tag match in L1, so pure miss */	mpcachestats[pid].L1_misses++;#ifdef GRAPHICS	L1_miss_count[pid]++;#endif /* GRAPHICS */	/* determine if writeback of current _L1_ line to L2 is needed */	/*  (note that this would not be needed if tag matched with invalid */	if (L1_states[pid][L1_line] == MODIFIED)	{	    /* reconstruct address of line being replaced */	    unsigned long	L2_wback_addr =		(L1_tags[pid][L1_line] << L1_tag_shift)		| (L1_line << L1_line_shift);	    /* determine which line in L2 it belongs in */	    unsigned int	L2_wback_line =		(L2_wback_addr >> L2_line_shift) & L2_line_mask;	    unsigned int	L2_wback_tag =		(L2_wback_addr >> L2_tag_shift);	    /* mark current L1 line (which will be written back to L2)	       as INVALID to allow 'CheckL1States()' to work properly	       (note that graphics are not informed of this change) */	    L1_states[pid][L1_line] = INVALID;	    	    /* check if other modified subblocks of wback L2 line are in L1 */	    /* if none, then change state of wback L2 line to just modified */	    /* (otherwise, remains modified_above) */	    if (CheckL1States (pid, L2_wback_tag, L2_wback_line, MODIFIED)== 0)		SET_L2_STATE (pid, L2_wback_line, MODIFIED);			    /* update count of writebacks to L2 */	    mpcachestats[pid].L2_writebacks++;	}	/* now check if we have the missing data in L2 */	if (L2_tags[pid][L2_line] == L2_tag	    && L2_states[pid][L2_line] != INVALID)	{	    if (! is_a_store)	    {		mpcachestats[pid].L2_hits++;	/* valid tag match for read */				/* this is the easy case; just use same state as L2,		   except if state is modified or modified_above */		SET_L1_STATE (pid, L1_line,			      (L2_states[pid][L2_line] == MODIFIED			       || L2_states[pid][L2_line] == MODIFIED_ABOVE) ?			      EXCLUSIVE : L2_states[pid][L2_line]);		L1_tags[pid][L1_line] = L1_tag;	    }	    else /* is_a_store */	    {		/* set tag in L1 */		L1_tags[pid][L1_line] = L1_tag;		/* check if an upgrade request is needed */		if (L2_states[pid][L2_line] == SHARED)		{		    mpcachestats[pid].L2_upgrades++;		    InvalidateOtherCaches (pid, /* who is invalidating */					   L2_tag, L2_line);		    /* make all other L1 subblocks exclusive		       except for the one that will change to modified */		    UpdateL1StatesExceptOne (pid, L2_tag, L2_line, EXCLUSIVE,					     L1_line);		    /* change L1 state to modified */		    SET_L1_STATE (pid, L1_line, MODIFIED);		    		    /* change L2 state */		    SET_L2_STATE (pid, L2_line, MODIFIED_ABOVE);		}		else /* either exclusive or already modified in L2 */		{		    mpcachestats[pid].L2_hits++; /* hit */		    /* change L1 and L2 states */		    SET_L1_STATE (pid, L1_line, MODIFIED);		    if (L2_states[pid][L2_line] == EXCLUSIVE)			mpcachestats[pid].exclusive_to_modified_changes++;		    SET_L2_STATE (pid, L2_line, MODIFIED_ABOVE);		}	    }	}	else	{	    /* pure miss in L2 */	    mpcachestats[pid].L2_misses++;#ifdef GRAPHICS	    L2_miss_count[pid]++;#endif /* GRAPHICS */	    	    /* check whether location of missing line in L2 needs mem wback */	    if (   L2_states[pid][L2_line] == MODIFIED		   || L2_states[pid][L2_line] == MODIFIED_ABOVE)	    {		/* mem writeback needed */		mpcachestats[pid].mem_writebacks++;				/* we must invalidate _all_ subblocks of this L2 line in L1 */		UpdateL1States (pid, L2_tag, L2_line, INVALID);	    }	    /* set tags in L1 and L2 */	    L1_tags[pid][L1_line] = L1_tag;	    L2_tags[pid][L2_line] = L2_tag;	    	    /* base on type of mem ref, update statistics for bus requests,	       update other caches, and finally update states in L1 and L2 */	    if (is_a_store)	    {		mpcachestats[pid].read_excl_requests++;		(void) CheckAndUpdateL2Copies (pid, L2_tag, L2_line, READ_EX);		SET_L1_STATE (pid, L1_line, MODIFIED);		SET_L2_STATE (pid, L2_line, MODIFIED_ABOVE);	    }	    else /* is a load */	    {		mpcachestats[pid].read_requests++;				/* with snooping, the data response would indicate		   whether this processor could set its final line state		   to shared or exclusive */		if (CheckAndUpdateL2Copies (pid, L2_tag, L2_line, READ) > 0)		{		    /* at least one other copy in another cache */		    SET_L1_STATE (pid, L1_line, SHARED);		    SET_L2_STATE (pid, L2_line, SHARED);		}		else		{		    /* no other copies in any other cache */		    SET_L1_STATE (pid, L1_line, EXCLUSIVE);		    SET_L2_STATE (pid, L2_line, EXCLUSIVE);		    /* keep track of how many exclusive responses for reads */		    mpcachestats[pid].exclusive_data_returns++;		}	    }	}    }#ifdef GRAPHICS    /* update miss ratio bar graph display for this processor */    if (graphics_flag && ++ref_count[pid] == MISS_INTERVAL)    {	int L1_miss_ratio =	    (int) (L1_miss_count[pid] / (double) MISS_INTERVAL * 100.0);	int L2_miss_ratio = (L1_miss_count[pid] == 0) ? 0 :	    (int) ((double) L2_miss_count[pid] / L1_miss_count[pid] * 100.0);	ref_count[pid] = L1_miss_count[pid] = L2_miss_count[pid] = 0;	if (L1_miss_ratio < L1_last_miss_ratio[pid])		ClearWindowArea (P_X + Q_OFFSET (pid, BAR_WIDTH, 1),				 100-L1_last_miss_ratio[pid],				 BAR_WIDTH,				 (L1_last_miss_ratio[pid] - L1_miss_ratio));	else	{	    SetColor (BLUE);	    DrawFilledRectangle (P_X + Q_OFFSET (pid, BAR_WIDTH, 1),				 100-L1_miss_ratio,				 BAR_WIDTH,				 (L1_miss_ratio - L1_last_miss_ratio[pid]));	}	if (L2_miss_ratio < L2_last_miss_ratio[pid])		ClearWindowArea (P_X + Q_OFFSET (pid, BAR_WIDTH, 2),				 100-L2_last_miss_ratio[pid],				 BAR_WIDTH,				 (L2_last_miss_ratio[pid] - L2_miss_ratio));	else	{	    SetColor (RED);	    DrawFilledRectangle (P_X + Q_OFFSET (pid, BAR_WIDTH, 2),				 100-L2_miss_ratio,				 BAR_WIDTH,				 (L2_miss_ratio - L2_last_miss_ratio[pid]));	}	L1_last_miss_ratio[pid] = L1_miss_ratio;	L2_last_miss_ratio[pid] = L2_miss_ratio;	FlushWindow ();    }    /* finally, make periodic checks of the X event queue for exposures       or unmap events in order to refresh or to alter mapped flag       (does not necessarily process X events in the order that they       appear in the queue, but should be sufficient for normal use) */    if (graphics_flag	&& ++window_event_interval_count >= WINDOW_EVENT_INTERVAL)    {	window_event_interval_count = 0;	if (ExposureCheck ())		/* any pending exposure events ? */	{	    ConsumeExposures ();	/* if so, consume them all */	    ConsumeMapEvents ();	/* along with any map events */	    RefreshEntireDisplay ();	/* then redraw graphics */	    if (! mapped)		/* we also use exposures to set */		mapped = 1;		/* mapped flag if it was unmapped */	}	if (UnmapCheck ())		/* any pending unmap events ? */	    mapped = 0;			/* if so, reset flag */    }#endif /* GRAPHICS */}/*------------------------------------------------------------------*/void	MPCacheReport (void){    int		i, j, **grid;    double	**fgrid;    unsigned 	int	total_read_requests = 0,			total_read_excl_requests = 0,			total_mem_writebacks = 0,			total_upgrade_requests = 0,			total_shared_responses = 0,			total_exclusive_responses = 0,			total_bus_requests = 0;    struct stat_stat_t	*stat_ptr;    unsigned int	*num_instructions;    /* retrieve array of instruction counts from statistics database */    stat_ptr = stat_find_stat (sim_sdb, "sim_num_instructions");    if (stat_ptr == NULL)	fatal ("unable to retrieve array of instruction counts"	       "for final report");    /* make pointer to array of counts */    num_instructions = stat_ptr->variant.for_uintarray.var;    for (i = 0; i < num_created_processes; i++)    {	/* compute final statistics */	mpcachestats[i].num_instructions = num_instructions[i];	mpcachestats[i].upgrade_requests =	    mpcachestats[i].L1_upgrades + mpcachestats[i].L2_upgrades;	mpcachestats[i].L1_miss_ratio =	    (double) mpcachestats[i].L1_misses / mpcachestats[i].L1_accesses	    * 100.0;	mpcachestats[i].L1_upgrade_miss_ratio =	    (double) mpcachestats[i].L1_upgrades / mpcachestats[i].L1_accesses	    * 100.0;	mpcachestats[i].L2_accesses = mpcachestats[i].L1_misses;	mpcachestats[i].L2_miss_ratio =	    (double) mpcachestats[i].L2_misses / mpcachestats[i].L2_accesses	    * 100.0;	mpcachestats[i].L2_upgrade_miss_ratio =	    (double) mpcachestats[i].L1_upgrades / mpcachestats[i].L2_accesses	    * 100.0;	mpcachestats[i].snoop_hit_ratio =	    (double) mpcachestats[i].snoop_hits	    / mpcachestats[i].external_bus_requests	    * 100.0;	total_read_requests += mpcachestats[i].read_requests;	total_read_excl_requests += mpcachestats[i].read_excl_requests;	total_mem_writebacks += mpcachestats[i].mem_writebacks;	total_upgrade_requests += mpcachestats[i].upgrade_requests;	total_shared_responses += mpcachestats[i].shared_data_responses;	total_exclusive_responses += mpcachestats[i].exclusive_data_responses;    }    /* create a integer "grid" and a floating-point "grid"       for the final output of statistics (note that both grids are       allocated to match the total number of statistics, but only a       portion of each one is used; inefficient, but simple) */    grid = (int **) malloc (NUM_STATISTICS * sizeof (int *));    for (j = 0; j < NUM_STATISTICS; j++)	grid[j] = (int *) malloc (num_created_processes * sizeof (int));    fgrid = (double **) malloc (NUM_STATISTICS * sizeof (double *));    for (j = 0; j < NUM_STATISTICS; j++)	fgrid[j] = (double *) malloc (num_created_processes * sizeof (double));    for (i = 0; i < num_created_processes; i++)	/* loop through processors */    {	int j = 0;	/* counter to step through the "grids" */	grid[j++][i] = mpcachestats[i].num_instructions;	grid[j++][i] = mpcachestats[i].L1_accesses;	grid[j++][i] = mpcachestats[i].L1_stores;	grid[j++][i] = mpcachestats[i].L1_hits;	grid[j++][i] = mpcachestats[i].L1_misses;	fgrid[j++][i] = mpcachestats[i].L1_miss_ratio;	grid[j++][i] = mpcachestats[i].L1_upgrades;	fgrid[j++][i] = mpcachestats[i].L1_upgrade_miss_ratio;	grid[j++][i] = mpcachestats[i].L2_writebacks;	grid[j++][i] = mpcachestats[i].L2_accesses;	grid[j++][i] = mpcachestats[i].L2_hits;	grid[j++][i] = mpcachestats[i].L2_misses;	fgrid[j++][i] = mpcachestats[i].L2_miss_ratio;	grid[j++][i] = mpcachestats[i].L2_upgrades;	fgrid[j++][i] = mpcachestats[i].L2_upgrade_miss_ratio;	grid[j++][i] = mpcachestats[i].mem_writebacks;	grid[j++][i] = mpcachestats[i].exclusive_to_modified_changes;	grid[j++][i] = mpcachestats[i].read_requests;	grid[j++][i] = mpcachestats[i].exclusive_data_returns;	grid[j++][i] = mpcachestats[i].read_excl_requests;	grid[j++][i] = mpcachestats[i].upgrade_requests;	grid[j++][i] = mpcachestats[i].external_bus_requests;	grid[j++][i] = mpcachestats[i].snoop_hits;	fgrid[j++][i] = mpcachestats[i].snoop_hit_ratio;	grid[j++][i] = mpcachestats[i].exclusive_to_shared_changes;	grid[j++][i] = mpcachestats[i].shared_data_responses;	grid[j++][i] = mpcachestats[i].exclusive_data_responses;	grid[j++][i] = mpcachestats[i].external_invalidations;    }    printf ("\n");    printf ("statistic\t");    for (i = 0; i < num_created_processes; i++)	printf ("\tPID %d", i);    printf ("\n\n");    for (j = 0; j < NUM_STATISTICS; j++)    {	printf ("%-23s", stat_names[j]);	for (i = 0; i < num_created_processes; i++)	    if (double_flags[j])		printf ("\t%.2f%%", fgrid[j][i]);	    else		printf ("\t%d", grid[j][i]);	printf ("\n");    }    for (j = 0; j < NUM_STATISTICS; j++)    {	free (grid[j]);	free (fgrid[j]);    }    free (grid);    free (fgrid);    printf ("\n");    printf ("===== Invalidation set size statistics ===== \n");    printf ("\n");    printf ("#procs\tfrequency\n");    for (i = 0; i <= num_created_processes - 1; i++)	printf ("%d\t%d\n", i, invalidation_set_size_histogram[i]);    printf ("\n");    if (invalidation_set_size_samples > 0)	printf ("avg. invalidation set size = %.2f\n",	    (double)invalidation_set_size_sum / invalidation_set_size_samples);    else	printf ("avg. invalidation set size = 0\n");    total_bus_requests =	  total_read_requests	+ total_read_excl_requests	+ total_upgrade_requests;    printf ("\n");    printf ("===== Total bus activity statistics =====\n");    printf ("\n");    printf ("total_requests\t\t%d\n", total_bus_requests);    printf ("\n");    printf ("read_requests\t\t%d\t(%5.2f%% of all requests)\n",	    total_read_requests,	    (double) total_read_requests / total_bus_requests * 100.0);    printf ("  cache-to-cache xfers\t%d\t\t(%5.2f%% of total_read_requests)\n",	    total_shared_responses,	    (double) total_shared_responses / total_read_requests * 100.0);    printf ("read_excl_requests\t%d\t(%5.2f%% of all requests)\n",	    total_read_excl_requests,	    (double) total_read_excl_requests / total_bus_requests * 100.0);    printf ("  cache-to-cache xfers\t%d\t\t(%5.2f%% of total_read_excl_requests)\n",	    total_exclusive_responses,	    (double) total_exclusive_responses / total_read_excl_requests * 100.0);    printf ("upgrade_requests\t%d\t(%5.2f%% of all requests)\n",	    total_upgrade_requests,	    (double) total_upgrade_requests / total_bus_requests * 100.0);    printf ("\n");    printf ("read & read_excl requests\t%d\t(%5.2f%% of all requests)\n",	    total_read_requests + total_read_excl_requests,	    (double) (total_read_requests + total_read_excl_requests)	    / total_bus_requests * 100.0);    printf ("total_mem_writebacks\t\t%d\t(%5.2f%% of read/read_excl)\n",	    total_mem_writebacks, (double) total_mem_writebacks	    / (total_read_requests + total_read_excl_requests) * 100.0);    printf ("sharing_writebacks\t\t%d\n", total_shared_responses);    printf ("writebacks per read/read_excl\t%.2f\n",	    (double) (total_mem_writebacks + total_shared_responses)	    / (total_read_requests + total_read_excl_requests));    printf ("writebacks per bus request\t%.2f\n",	    (double) (total_mem_writebacks + total_shared_responses)	    / total_bus_requests);#ifdef GRAPHICS    /* if graphics enabled for this run, pause before terminating so that       the final cache contents displayed on the screen may be viewed as       long as necessary; print message on the graphics window to press       return to continue       (if window gets obscured after this point, it will not be refreshed;	making the appropriate modifications for full refresh capability is	left as an exercise for the reader.....) */    if (graphics_flag)    {	char	s[128];	SetColor (BLACK);	DrawLeftString ("Simulation complete; press return in the shell window"			" to terminate",			10, WIN_HEIGHT - 20);	FlushWindow ();	/* print the same message to shell window */	printf ("\nSimulation complete; press return to terminate\n");	fflush (stdout);		gets (s);    }#endif /* GRAPHICS */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -