Ejemplo n.º 1
0
double _ssd_clean_block_fully(int blk, int plane_num, int elem_num, ssd_element_metadata *metadata, ssd_t *s)
{
    double cost = 0;
    plane_metadata *pm = &metadata->plane_meta[plane_num];
	ssd_power_element_stat *power_stat = &(s->elements[elem_num].power_stat);

    ASSERT((pm->clean_in_progress == 0) && (pm->clean_in_block = -1));
    pm->clean_in_block = blk;
    pm->clean_in_progress = 1;

    // stat
    pm->num_cleans ++;
    s->elements[elem_num].stat.num_clean ++;

	cost = s->params.block_erase_latency;
    //Micky:add the power consumption of the erase
	ssd_power_flash_calculate(SSD_POWER_FLASH_ERASE, s->params.block_erase_latency, power_stat, s);

	ssd_update_free_block_status(blk, plane_num, metadata, s);
	ssd_update_block_lifetime(simtime+cost, blk, metadata);
	pm->clean_in_progress = 0;
	pm->clean_in_block = -1;

    return cost;
}
Ejemplo n.º 2
0
double ssd_switch(ssd_t *s, ssd_element_metadata *metadata, ssd_power_element_stat *power_stat, int lbn, int elem_num)
{
	int d_block = metadata->lba_table[lbn];
	int log_index = metadata->block_usage[d_block].log_index;
	int log_block = metadata->log_data[log_index].bsn;
	int num_valid = 0;
	int num_valid_d = metadata->block_usage[d_block].num_valid;
	int num_valid_u = metadata->block_usage[log_block].num_valid;
	int d_plane_num = metadata->block_usage[d_block].plane_num;
	int log_plane_num = metadata->block_usage[log_block].plane_num;

	int i;
	double cost = 0.0;

	metadata->plane_meta[d_plane_num].clean_in_block = d_block;
	metadata->plane_meta[d_plane_num].clean_in_progress = 1;

	//switch
	for( i = 0 ; i < s->params.pages_per_block ; i++) {
		metadata->block_usage[d_block].page[i] = -1;
		metadata->log_data[log_index].page[i] = -1;
	}
	metadata->lba_table[lbn] = log_block;

	//update stat
	metadata->block_usage[d_block].log_index = -1;
	metadata->log_data[log_index].bsn = -1;
	metadata->log_data[log_index].data_block = -1;
	metadata->num_log--;
	metadata->log_pos = log_index;
	//update block usage
	metadata->block_usage[d_block].num_valid = 0;
	//update plane data
	metadata->plane_meta[d_plane_num].valid_pages -= num_valid_d;

	//erase two block(D)
	cost += s->params.block_erase_latency;
	ssd_power_flash_calculate(SSD_POWER_FLASH_ERASE, s->params.block_erase_latency, power_stat, s);
	ssd_update_free_block_status(d_block, d_plane_num, metadata, s);
	ssd_update_block_lifetime(simtime+cost, d_block, metadata);
	metadata->plane_meta[d_plane_num].clean_in_block = 0;
	metadata->plane_meta[d_plane_num].clean_in_progress = -1;
	metadata->plane_meta[d_plane_num].num_cleans++;
	s->elements[elem_num].stat.num_clean++;
	s->elements[elem_num].stat.num_switch++;

	return cost;
}
Ejemplo n.º 3
0
//block_erase_opeeration
double _ssd_erase_block_osr(ssd_t *s, ssd_element_metadata *metadata, int block, int plane_num, ssd_power_element_stat *power_stat)
{
	double cost =0.0;

	if ((metadata->block_usage[block].num_valid == 0)&&(metadata->block_usage[block].state == SSD_BLOCK_SEALED)) {
		// add the cost of erasing the block
		//add the power consumption of the erase
		plane_metadata *pm = &metadata->plane_meta[plane_num];

		cost = s->params.block_erase_latency;
		ssd_power_flash_calculate(SSD_POWER_FLASH_ERASE, cost, power_stat, s);

        ssd_update_free_block_status(block, plane_num, metadata, s);
		ssd_update_block_lifetime(simtime+s->params.block_erase_latency, block, metadata);
		pm->clean_in_progress = 0;
        pm->clean_in_block = -1;
    }

	return cost;
}
Ejemplo n.º 4
0
/*
 * this routine cleans one page at a time in a block. if all the
 * valid pages are moved, then the block is erased.
 */
static double _ssd_clean_block_partially(int plane_num, int elem_num, ssd_t *s)
{
    ssd_element_metadata *metadata = &(s->elements[elem_num].metadata);
    plane_metadata *pm = &metadata->plane_meta[plane_num];
    double cost = 0;
    int block;
    int i;

    ASSERT(pm->clean_in_progress);
    block = pm->clean_in_block;

    if (metadata->block_usage[block].num_valid > 0) {
        // pick a page that is not yet cleaned and move it
        for (i = 0; i < s->params.pages_per_block; i ++) {
            int lp_num = metadata->block_usage[block].page[i];

            if (lp_num != -1) {
                cost += ssd_clean_one_page(lp_num, i, block, plane_num, elem_num, metadata, s);
                break;
            }
        }
    }

    // if we've moved all the valid pages out of this block,
    // then we're done with it. so, erase it and update the
    // system state.
    if (metadata->block_usage[block].num_valid == 0) {
        // add the cost of erasing the block
        cost += s->params.block_erase_latency;

        ssd_update_free_block_status(block, plane_num, metadata, s);
        ssd_update_block_lifetime(simtime+cost, block, metadata);
        pm->clean_in_progress = 0;
        pm->clean_in_block = -1;
    }

    return cost;
}
Ejemplo n.º 5
0
double ssd_fullmerge(ssd_t *s, ssd_element_metadata *metadata, ssd_power_element_stat *power_stat, int lbn, int elem_num)
{
	int prev_block = metadata->lba_table[lbn];
	int log_index = metadata->block_usage[prev_block].log_index;
	int log_block = metadata->log_data[log_index].bsn;
	int num_valid = 0;
	int num_valid_d = metadata->block_usage[prev_block].num_valid;
	int num_valid_u = metadata->block_usage[log_block].num_valid;
	int prev_plane_num = metadata->block_usage[prev_block].plane_num;
	int log_plane_num = metadata->block_usage[log_block].plane_num;
	int plane_num;

	int active_block;
	int i;
	double cost = 0.0;
	double r_cost, w_cost, xfer_cost;

	//set active_block
	metadata->active_block = metadata->plane_meta[prev_plane_num].active_block;
	active_block = metadata->active_block;
	_ssd_alloc_active_block(prev_plane_num, elem_num, s);
	plane_num = metadata->block_usage[active_block].plane_num;
	metadata->plane_meta[prev_plane_num].clean_in_block = prev_block;
	metadata->plane_meta[prev_plane_num].clean_in_progress = 1;
	metadata->plane_meta[log_plane_num].clean_in_block = prev_block;
	metadata->plane_meta[log_plane_num].clean_in_progress = 1;

	//page state copy & init page state
	for( i = 0 ; i < s->params.pages_per_block ; i++) {
		if((metadata->block_usage[prev_block].page[i] == 1) || (metadata->log_data[log_index].page[i] != -1)){
			metadata->block_usage[active_block].page[i] = 1;
		}
		metadata->block_usage[prev_block].page[i] = -1;
		metadata->log_data[log_index].page[i] = -1;
		metadata->block_usage[log_block].page[i] = -1;
	}
	metadata->lba_table[lbn] = active_block;

	//update stat
	//update log_table
	metadata->block_usage[prev_block].log_index = -1;
	metadata->log_data[log_index].bsn = -1;
	metadata->log_data[log_index].data_block = -1;
	metadata->log_pos = log_index;
	metadata->num_log--;
	//update block usage
	metadata->block_usage[prev_block].num_valid = 0;
	metadata->block_usage[log_block].num_valid = 0;
	//update plane data
	metadata->plane_meta[prev_plane_num].valid_pages -= num_valid_d;
	metadata->plane_meta[log_plane_num].valid_pages -= num_valid_u;
	num_valid += num_valid_d;
	num_valid += num_valid_u;
	if(num_valid > s->params.pages_per_block) {
		fprintf(outputfile3, "Error number of pages : valid_page %d, Real_page %d\n", num_valid, s->params.pages_per_block);
		fprintf(outputfile3, "Error elem_num %d, lbn %d, original block %d, log block %d\n", elem_num, lbn, prev_block, log_block);
		exit(-1);
	}
	metadata->block_usage[active_block].num_valid = num_valid;
	metadata->plane_meta[plane_num].valid_pages += num_valid;


	//data tranfer cost
	//read
	r_cost = s->params.page_read_latency * num_valid;
	cost += r_cost;
	ssd_power_flash_calculate(SSD_POWER_FLASH_READ, r_cost, power_stat, s);

	//write
	w_cost = s->params.page_write_latency * num_valid;
	cost += w_cost;
	ssd_power_flash_calculate(SSD_POWER_FLASH_WRITE, w_cost, power_stat, s);

	//transfer cost
	for( i = 0 ; i < num_valid ; i++) {
		double xfer_cost;
		xfer_cost = ssd_crossover_cost(s, metadata, power_stat, prev_block, active_block);
		cost += xfer_cost;
		s->elements[elem_num].stat.tot_xfer_cost += xfer_cost;
	}

	//erase two block(D)
	cost += s->params.block_erase_latency;
	ssd_power_flash_calculate(SSD_POWER_FLASH_ERASE, s->params.block_erase_latency, power_stat, s);
	ssd_update_free_block_status(prev_block, prev_plane_num, metadata, s);
	ssd_update_block_lifetime(simtime+cost, prev_block, metadata);
	metadata->plane_meta[prev_plane_num].num_cleans++;
	metadata->plane_meta[prev_plane_num].clean_in_block = 0;
	metadata->plane_meta[prev_plane_num].clean_in_progress = -1;

	//erase two block(U)
	cost += s->params.block_erase_latency;
	ssd_power_flash_calculate(SSD_POWER_FLASH_ERASE, s->params.block_erase_latency, power_stat, s);
	ssd_update_free_block_status(log_block, log_plane_num, metadata, s);
	ssd_update_block_lifetime(simtime+cost, log_block, metadata);
	metadata->plane_meta[log_plane_num].num_cleans++;
	metadata->plane_meta[log_plane_num].clean_in_block = 0;
	metadata->plane_meta[log_plane_num].clean_in_progress = -1;

	//erase stat update
	s->elements[elem_num].stat.pages_moved += num_valid;
	s->elements[elem_num].stat.num_clean += 2;
	s->elements[elem_num].stat.num_fullmerge++;

	return cost;
}
Ejemplo n.º 6
0
double ssd_replacement(ssd_t *s, int elem_num, int lbn)
{
	ssd_element_metadata *metadata;
	ssd_power_element_stat *power_stat;
	int block;
	int log_index;
	int prev_log_block;
	int prev_plane_num;
	int log_block;
	int plane_num;
	int num_valid;
	double cost = 0.0;
	double r_cost, w_cost, xfer_cost;
	int i,j;

	metadata = &(s->elements[elem_num].metadata);
	power_stat = &(s->elements[elem_num].power_stat);

	block = metadata->lba_table[lbn];
	log_index = metadata->block_usage[block].log_index;
	prev_log_block = metadata->log_data[log_index].bsn;
	prev_plane_num = metadata->block_usage[prev_log_block].plane_num;
	num_valid = metadata->block_usage[prev_log_block].num_valid;

	//alloc new logblock and erase old logblock
	log_block = metadata->plane_meta[prev_plane_num].active_block;
	_ssd_alloc_active_block(prev_plane_num, elem_num, s);
	plane_num = metadata->block_usage[log_block].plane_num;
	metadata->log_data[log_index].bsn = log_block; 
	//move page old to new 
	j = 0;
	for( i = 0 ; i < s->params.pages_per_block ; i++) {
		if( metadata->log_data[log_index].page[i] != -1) {
			metadata->log_data[log_index].page[i] = j;
			metadata->block_usage[log_block].page[j] = 1;
			metadata->block_usage[log_block].num_valid++;
			j++;
		}
		metadata->block_usage[prev_log_block].page[i] = -1;
	}
	metadata->block_usage[prev_log_block].num_valid = 0;

	//plane metadata update
	metadata->plane_meta[prev_plane_num].valid_pages -= metadata->block_usage[log_block].num_valid;
	metadata->plane_meta[plane_num].valid_pages += metadata->block_usage[log_block].num_valid;

	//cost
	//read
	r_cost = s->params.page_read_latency * num_valid;
	cost += r_cost;
	ssd_power_flash_calculate(SSD_POWER_FLASH_READ, r_cost, power_stat, s);

	//write
	w_cost = s->params.page_write_latency * num_valid;
	cost += w_cost;
	ssd_power_flash_calculate(SSD_POWER_FLASH_WRITE, w_cost, power_stat, s);

	//transfer cost
	for( i = 0 ; i < num_valid ; i++) {
		double xfer_cost;
		xfer_cost = ssd_crossover_cost(s, metadata, power_stat, prev_log_block, log_block);
		cost += xfer_cost;
		s->elements[elem_num].stat.tot_xfer_cost += xfer_cost;
	}

	//erase U block
	cost += s->params.block_erase_latency;
	ssd_power_flash_calculate(SSD_POWER_FLASH_ERASE, s->params.block_erase_latency, power_stat, s);
	ssd_update_free_block_status(prev_log_block, prev_plane_num, metadata, s);
	ssd_update_block_lifetime(simtime+cost, prev_log_block, metadata);
	s->elements[elem_num].stat.pages_moved += num_valid;
	s->elements[elem_num].stat.num_clean ++;
	s->elements[elem_num].stat.num_replacement++;
	metadata->plane_meta[prev_plane_num].num_cleans++;

	return cost;

}