Example #1
0
void moesi_handler_find_and_lock(int event, void *data)
{
	struct moesi_stack_t *stack = data, *ret = stack->retstack, *newstack;
	struct ccache_t *ccache = stack->ccache;

	if (event == EV_MOESI_FIND_AND_LOCK)
	{
		int hit;
		cache_debug("  %lld %lld 0x%x %s find and lock (blocking=%d)\n", CYCLE, ID,
			stack->addr, ccache->name, stack->blocking);

		/* Default return values */
		ret->err = 0;
		ret->set = 0;
		ret->way = 0;
		ret->status = 0;
		ret->tag = 0;

		/* Look for block. */
		hit = ccache_find_block(ccache, stack->addr, &stack->set,
			&stack->way, &stack->tag, &stack->status);
		if (hit)
			cache_debug("    %lld 0x%x %s hit: set=%d, way=%d, status=%d\n", ID,
				stack->tag, ccache->name, stack->set, stack->way, stack->status);

		/* Stats */
		ccache->accesses++;
		if (hit)
			ccache->hits++;
		if (stack->read) {
			ccache->reads++;
			stack->blocking ? ccache->blocking_reads++ : ccache->non_blocking_reads++;
			if (hit)
				ccache->read_hits++;
		} else {
			ccache->writes++;
			stack->blocking ? ccache->blocking_writes++ : ccache->non_blocking_writes++;
			if (hit)
				ccache->write_hits++;
		}
		if (!stack->retry) {
			ccache->no_retry_accesses++;
			if (hit)
				ccache->no_retry_hits++;
			if (stack->read) {
				ccache->no_retry_reads++;
				if (hit)
					ccache->no_retry_read_hits++;
			} else {
				ccache->no_retry_writes++;
				if (hit)
					ccache->no_retry_write_hits++;
			}
		}

		/* Miss */
		if (!hit) {
			
			assert(!stack->blocking);
			assert(ccache != main_memory);

			/* Find victim */
			stack->way = cache_replace_block(ccache->cache, stack->set);
			cache_get_block(ccache->cache, stack->set, stack->way, NULL, &stack->status);
			assert(stack->status || !dir_entry_group_shared_or_owned(ccache->dir,
				stack->set, stack->way));
			cache_debug("    %lld 0x%x %s miss -> lru: set=%d, way=%d, status=%d\n",
				ID, stack->tag, ccache->name, stack->set, stack->way, stack->status);
		}

		/* Lock entry */
		stack->dir_lock = ccache_get_dir_lock(ccache, stack->set, stack->way);
		if (stack->dir_lock->lock && !stack->blocking) {
			cache_debug("    %lld 0x%x %s block already locked: set=%d, way=%d\n",
				ID, stack->tag, ccache->name, stack->set, stack->way);
			ret->err = 1;
			moesi_stack_return(stack);
			return;
		}
		if (!dir_lock_lock(stack->dir_lock, EV_MOESI_FIND_AND_LOCK, stack))
			return;

		/* Entry is locked. Record the transient tag so that a subsequent lookup
		 * detects that the block is being brought. */
		if (ccache->cache)
			cache_set_transient_tag(ccache->cache, stack->set, stack->way, stack->tag);

		/* On miss, evict if victim is a valid block. */
		if (!hit && stack->status) {
			stack->eviction = 1;
			newstack = moesi_stack_create(stack->id, ccache, 0,
				EV_MOESI_FIND_AND_LOCK_FINISH, stack);
			newstack->set = stack->set;
			newstack->way = stack->way;
			esim_schedule_event(EV_MOESI_EVICT, newstack, ccache->lat);
			return;
		}

		/* Access latency */
		esim_schedule_event(EV_MOESI_FIND_AND_LOCK_FINISH, stack, ccache->lat);
		return;
	}

	if (event == EV_MOESI_FIND_AND_LOCK_FINISH)
	{
		cache_debug("  %lld %lld 0x%x %s find and lock finish (err=%d)\n", CYCLE, ID,
			stack->tag, ccache->name, stack->err);

		/* If evict produced err, return err */
		if (stack->err) {
			cache_get_block(ccache->cache, stack->set, stack->way, NULL, &stack->status);
			assert(stack->status);
			assert(stack->eviction);
			ret->err = 1;
			dir_lock_unlock(stack->dir_lock);
			moesi_stack_return(stack);
			return;
		}

		/* Eviction */
		if (stack->eviction) {
			ccache->evictions++;
			cache_get_block(ccache->cache, stack->set, stack->way, NULL, &stack->status);
			assert(!stack->status);
		}

		/* Return */
		ret->err = 0;
		ret->set = stack->set;
		ret->way = stack->way;
		ret->status = stack->status;
		ret->tag = stack->tag;
		ret->dir_lock = stack->dir_lock;
		moesi_stack_return(stack);
		return;
	}

	abort();
}
Example #2
0
/* Event handler for EV_MEM_SYSTEM_END_COMMAND.
 * The event data is a string of type 'char *' that needs to be deallocated
 * after processing this event. */
void mem_system_end_command_handler(int event, void *data)
{
	char *command_line = data;
	char command[MAX_STRING_SIZE];

	char msg[MAX_STRING_SIZE];
	char msg_detail[MAX_STRING_SIZE];

	char *msg_str = msg;
	int msg_size = sizeof msg;

	char *msg_detail_str = msg_detail;
	int msg_detail_size = sizeof msg_detail;

	int test_failed;

	struct list_t *token_list;

	/* Split command in tokens, skip command */
	token_list = str_token_list_create(command_line, " ");
	assert(list_count(token_list));

	/* Get command */
	mem_system_command_get_string(token_list, command_line, command, sizeof command);

	/* Messages */
	test_failed = 0;
	*msg_str = '\0';
	*msg_detail_str = '\0';

	/* Command 'SetBlock' */
	if (!strcasecmp(command, "CheckBlock"))
	{
		struct mod_t *mod;

		int set;
		int way;
		int tag;
		int tag_check;

		int state;
		int state_check;

		mod = mem_system_command_get_mod(token_list, command_line);
		mem_system_command_get_set_way(token_list, command_line, mod, &set, &way);
		tag = mem_system_command_get_hex(token_list, command_line);
		state = mem_system_command_get_state(token_list, command_line);
		mem_system_command_end(token_list, command_line);

		/* Check that module serves address */
		if (!mod_serves_address(mod, tag))
			fatal("%s: %s: module does not serve address 0x%x.\n\t> %s",
				__FUNCTION__, mod->name, tag, command_line);

		/* Output */
		str_printf(&msg_str, &msg_size,
			"check module %s, set %d, way %d - state %s, tag 0x%x",
			mod->name, set, way, str_map_value(&cache_block_state_map, state), tag);

		/* Check */
		cache_get_block(mod->cache, set, way, &tag_check, &state_check);
		if (tag != tag_check)
		{
			test_failed = 1;
			str_printf(&msg_detail_str, &msg_detail_size,
				"\ttag 0x%x found, but 0x%x expected\n",
				tag_check, tag);
		}
		if (state != state_check)
		{
			test_failed = 1;
			str_printf(&msg_detail_str, &msg_detail_size,
				"\tstate %s found, but %s expected\n",
				str_map_value(&cache_block_state_map, state_check),
				str_map_value(&cache_block_state_map, state));
		}
	}

	/* Command 'CheckOwner' */
	else if (!strcasecmp(command, "CheckOwner"))
	{
		struct mod_t *mod;
		struct mod_t *owner;
		struct mod_t *owner_check = NULL;

		struct net_node_t *net_node;

		struct dir_entry_t *dir_entry;

		int set;
		int way;

		int sub_block;

		/* Read fields */
		mod = mem_system_command_get_mod(token_list, command_line);
		mem_system_command_get_set_way(token_list, command_line, mod, &set, &way);
		sub_block = mem_system_command_get_sub_block(token_list, command_line, mod, set, way);
		owner = mem_system_command_get_mod(token_list, command_line);
		mem_system_command_end(token_list, command_line);

		/* Get actual owner */
		owner_check = NULL;
		if (mod->dir)
		{
			dir_entry = dir_entry_get(mod->dir, set, way, sub_block);
			if (dir_entry->owner >= 0)
			{
				assert(mod->high_net);
				net_node = list_get(mod->high_net->node_list, dir_entry->owner);
				owner_check = net_node->user_data;
			}
		}

		/* Message */
		str_printf(&msg_str, &msg_size,
			"check owner at module %s, set %d, way %d, subblock %d - %s",
			mod->name, set, way, sub_block, owner ? owner->name : "None");

		/* Check match */
		if (owner != owner_check)
		{
			test_failed = 1;
			str_printf(&msg_detail_str, &msg_detail_size,
				"\towner %s found, but %s expected\n",
				owner_check ? owner_check->name : "None",
				owner ? owner->name : "None");
		}
	}

	/* Command 'CheckSharers' */
	else if (!strcasecmp(command, "CheckSharers"))
	{
		struct mod_t *mod;
		struct mod_t *sharer;

		struct net_node_t *node;

		int set;
		int way;

		int sub_block;
		int node_index;

		struct linked_list_t *sharers_list;
		struct linked_list_t *sharers_check_list;

		/* Read fields */
		mod = mem_system_command_get_mod(token_list, command_line);
		mem_system_command_get_set_way(token_list, command_line, mod, &set, &way);
		sub_block = mem_system_command_get_sub_block(token_list, command_line, mod, set, way);
		mem_system_command_expect(token_list, command_line);

		/* Construct list of expected sharers */
		sharers_list = linked_list_create();
		while (list_count(token_list))
		{
			sharer = mem_system_command_get_mod(token_list, command_line);
			linked_list_add(sharers_list, sharer);
		}

		/* Output */
		str_printf(&msg_str, &msg_size,
			"check sharers at module %s, set %d, way %d, subblock %d - { ",
			mod->name, set, way, sub_block);
		LINKED_LIST_FOR_EACH(sharers_list)
		{
			sharer = linked_list_get(sharers_list);
			if (sharer)
				str_printf(&msg_str, &msg_size, "%s ", sharer->name);
		}
		str_printf(&msg_str, &msg_size, "}");

		/* Construct list of actual sharers */
		sharers_check_list = linked_list_create();
		assert(mod->high_net);
		for (node_index = 0; node_index < mod->high_net->node_count; node_index++)
		{
			if (!dir_entry_is_sharer(mod->dir, set, way, sub_block, node_index))
				continue;
			node = list_get(mod->high_net->node_list, node_index);
			sharer = node->user_data;
			linked_list_add(sharers_check_list, sharer);
		}

		/* Remove in actual sharers everything from expected sharers */
		LINKED_LIST_FOR_EACH(sharers_list)
		{
			/* Get expected sharer */
			sharer = linked_list_get(sharers_list);
			if (!sharer)
				continue;

			/* Check that it's an actual sharer */
			linked_list_find(sharers_check_list, sharer);
			if (sharers_check_list->error_code)
			{
				test_failed = 1;
				str_printf(&msg_detail_str, &msg_detail_size,
					"\tsharer %s expected, but not found\n",
					sharer->name);
			}

			/* Remove from actual sharers */
			linked_list_remove(sharers_check_list);
		}

		/* Check that there is no actual sharer left */
		LINKED_LIST_FOR_EACH(sharers_check_list)
		{
			sharer = linked_list_get(sharers_check_list);
			test_failed = 1;
			str_printf(&msg_detail_str, &msg_detail_size,
				"\tsharer %s found, but not expected\n",
				sharer->name);
		}

		/* Free lists */
		linked_list_free(sharers_list);
		linked_list_free(sharers_check_list);
	}

	/* Command 'CheckLink' */
	else if (!strcasecmp(command, "CheckLink"))
Example #3
0
void estadisticas_por_intervalos(long long intervalo){

//double latencia;
int z, x, y, k, i;
//long long ipc;

if((intervalo_anterior + ventana_muestreo) > intervalo )
	return;


long long latency = mem_stats.load_latency - ciclos_mem_stats_anterior.load_latency;
long long contador = mem_stats.load_latency_count - ciclos_mem_stats_anterior.load_latency_count;
/*
// mshr

mem_stats.superintervalo_latencia += latency;
mem_stats.superintervalo_contador += contador;

mem_stats.superintervalo_operacion += gpu_stats.total - instrucciones_gpu_stats_anterior.total;
mem_stats.superintervalo_ciclos += cycle - ipc_last_cycle;


if(mshr_control_enabled && !(gpu_stats.total % 500000))
{
	mshr_control(mem_stats.superintervalo_contador ? mem_stats.superintervalo_latencia/mem_stats.superintervalo_contador : 0,  mem_stats.superintervalo_operacion/mem_stats.superintervalo_ciclos);
	mem_stats.superintervalo_latencia = 0;
  	mem_stats.superintervalo_contador = 0;
     	mem_stats.superintervalo_operacion = 0;
        mem_stats.superintervalo_ciclos = 0;
}
*/ 


fran_debug_general("%lld %lld ",latency, contador);

fran_debug_general("%lld ",mem_stats.mod_level[0].coalesce - ciclos_mem_stats_anterior.mod_level[0].coalesce);
fran_debug_general("%lld ",mem_stats.mod_level[0].accesses - ciclos_mem_stats_anterior.mod_level[0].accesses);

fran_debug_general("%lld ",mem_stats.mod_level[1].coalesce - ciclos_mem_stats_anterior.mod_level[1].coalesce);
fran_debug_general("%lld ",mem_stats.mod_level[1].accesses - ciclos_mem_stats_anterior.mod_level[1].accesses);
fran_debug_general("%lld ",mem_stats.mod_level[1].hits - ciclos_mem_stats_anterior.mod_level[1].hits);
fran_debug_general("%lld ",mem_stats.mod_level[1].invalidations - ciclos_mem_stats_anterior.mod_level[1].invalidations);
fran_debug_general("%lld ",mem_stats.mod_level[2].coalesce - ciclos_mem_stats_anterior.mod_level[2].coalesce);
fran_debug_general("%lld ",mem_stats.mod_level[2].accesses - ciclos_mem_stats_anterior.mod_level[2].accesses);
fran_debug_general("%lld ",mem_stats.mod_level[2].hits - ciclos_mem_stats_anterior.mod_level[2].hits);
fran_debug_general("%lld ",mem_stats.mod_level[2].invalidations - ciclos_mem_stats_anterior.mod_level[2].invalidations);


fran_debug_general("%lld ",mem_stats.mod_level[1].busy_cicles_in - ciclos_mem_stats_anterior.mod_level[1].busy_cicles_in);
fran_debug_general("%lld ",mem_stats.mod_level[1].busy_cicles_out - ciclos_mem_stats_anterior.mod_level[1].busy_cicles_out);
fran_debug_general("%lld ",mem_stats.mod_level[2].busy_cicles_in - ciclos_mem_stats_anterior.mod_level[2].busy_cicles_in);
fran_debug_general("%lld ",mem_stats.mod_level[2].busy_cicles_out - ciclos_mem_stats_anterior.mod_level[2].busy_cicles_out);
fran_debug_general("%lld ",mem_stats.mod_level[1].latencia_red_acc - ciclos_mem_stats_anterior.mod_level[1].latencia_red_acc);
fran_debug_general("%lld ",mem_stats.mod_level[1].latencia_red_cont - ciclos_mem_stats_anterior.mod_level[1].latencia_red_cont);
fran_debug_general("%lld ",mem_stats.mod_level[2].latencia_red_acc - ciclos_mem_stats_anterior.mod_level[2].latencia_red_acc);
fran_debug_general("%lld ",mem_stats.mod_level[2].latencia_red_cont - ciclos_mem_stats_anterior.mod_level[2].latencia_red_cont);

memcpy(&ciclos_mem_stats_anterior,&mem_stats,sizeof(struct mem_system_stats));


int tag_ptr;
int state_ptr;
contador = 0;
long long locked[5] = {0,0,0,0,0};
struct mod_t *mod;
struct cache_t *cache;
struct dir_t *dir;
long long replica = 0;
long long compartido = 0;

for (k = 0; k < list_count(mem_system->mod_list); k++)
{
	mod = list_get(mem_system->mod_list, k);

        dir = mod->dir;
        cache = mod->cache;

        for (x = 0; x < dir->xsize; x++)
        {
	        for (y = 0; y < dir->ysize; y++)
        	{
			 struct dir_lock_t *dir_lock =  &dir->dir_lock[x * dir->ysize + y];

                        if(dir_lock->lock)
                                locked[mod->level]++;

		        if(mod->level != 2)
                		continue;


                	cache_get_block(cache, x, y, &tag_ptr, &state_ptr);
                        if(state_ptr)
                        {
                        	for (z = 0; z < dir->zsize; z++)
                                {
                                	contador = 0;
                                        for (i = 0; i < dir->num_nodes; i++)
                                        {
                                        	if (dir_entry_is_sharer(dir, x, y, z, i))
                                                {
                                                	contador++;
                                                        if(contador == 1)
                                                        {
                                                        	compartido++;
                                                        }
							else
                                                        {
                                                        	replica++;
							}
                                                }
                                        }
                                }
                        }
                }
        }
}

fran_debug_general("%lld ",compartido);
fran_debug_general("%lld ",replica);
fran_debug_general("%lld ",locked[1]);
fran_debug_general("%lld ",locked[2]);

fran_debug_general("%lld %lld\n",intervalo - intervalo_anterior , intervalo);

intervalo_anterior = intervalo;

}