int main(int argc, char **argv){ long vaddr; double arrive_time; load_config(); print_config(NULL); Ssd ssd; printf("INITIALIZING SSD Bimodal\n"); srandom(1); int preIO = SSD_SIZE * PACKAGE_SIZE * DIE_SIZE * PLANE_SIZE * BLOCK_SIZE; if (FTL_IMPLEMENTATION == 0) // PAGE preIO -= 16*BLOCK_SIZE; if (FTL_IMPLEMENTATION == 1) // BAST preIO -= (BAST_LOG_PAGE_LIMIT*BLOCK_SIZE)*2; if (FTL_IMPLEMENTATION == 2) // FAST preIO -= (FAST_LOG_PAGE_LIMIT*BLOCK_SIZE)*1.1; if (FTL_IMPLEMENTATION > 2) // DFTL BIFTL preIO -= 512; int deviceSize = 3145216; if (preIO > deviceSize) preIO = deviceSize; printf("Writes %i pages for startup out of %i total pages.\n", preIO, SSD_SIZE * PACKAGE_SIZE * DIE_SIZE * PLANE_SIZE * BLOCK_SIZE); double start_time = 0; double timeMultiplier = 10000; double read_time = 0; double write_time = 0; double trim_time = 0; unsigned long num_reads = 0; unsigned long num_writes = 0; unsigned long num_trims = 0; std::vector<double> avgsTrim; std::vector<double> avgsWrite1; std::vector<double> avgsRead1; std::vector<double> avgsRead2; std::vector<double> avgsRead3; std::vector<double> avgsTrim2; std::vector<double> avgsWrite2; std::vector<double> avgsRead4; std::vector<double> avgsWrite3; avgsTrim.reserve(1024*64); avgsWrite1.reserve(1024*64); avgsRead1.reserve(1024*64); avgsRead2.reserve(1024*64); avgsRead3.reserve(1024*64); avgsTrim2.reserve(1024*64); avgsWrite2.reserve(1024*64); avgsRead4.reserve(1024*64); avgsWrite3.reserve(1024*64); // Reset statistics ssd.reset_statistics(); // 1. Write random to the size of the device srand(1); double afterFormatStartTime = 0; //for (int i=0; i<preIO/3*2;i++) for (int i=0; i<preIO*1.1;i++) //for (int i=0; i<700000;i++) { long int r = random()%preIO; double d = ssd.event_arrive(WRITE, r, 1, afterFormatStartTime); afterFormatStartTime += d; if (i % 10000 == 0) printf("Wrote %i %f\n", i,d ); } start_time = afterFormatStartTime; // Reset statistics ssd.reset_statistics(); // 2. Trim an area. ( We let in be 512MB (offset 131072 pages or 2048 blocks) into the address space, and then 256MB (1024 blocks or 65536 pages) ) int startTrim = 2048*64; //131072 int endTrim = 3072*64; //196608 /* Test 1 */ for (int i=startTrim; i<endTrim;i++) { trim_time = ssd.event_arrive(TRIM, i, 1, ((start_time+arrive_time)*timeMultiplier)); avgsTrim.push_back(trim_time); num_trims++; arrive_time += trim_time; if (i % 1000 == 0) printf("Trim: %i %f\n", i, trim_time); } for (int i=startTrim; i<endTrim;i++) { trim_time = ssd.event_arrive(READ, i, 1, ((start_time+arrive_time)*timeMultiplier)); avgsRead1.push_back(trim_time); num_trims++; arrive_time += trim_time; if (i % 1000 == 0) printf("Read: %i %f\n", i, trim_time); } for (int i=startTrim; i<endTrim;i++) { trim_time = ssd.event_arrive(READ, i, 1, ((start_time+arrive_time)*timeMultiplier)); avgsRead2.push_back(trim_time); num_trims++; arrive_time += trim_time; if (i % 1000 == 0) printf("Read: %i %f\n", i, trim_time); } for (int i=startTrim; i<endTrim;i++) { trim_time = ssd.event_arrive(WRITE, i, 1, ((start_time+arrive_time)*timeMultiplier)); avgsWrite1.push_back(trim_time); num_trims++; arrive_time += trim_time; if (i % 1000 == 0) printf("Write: %i %f\n", i, trim_time); } for (int i=startTrim; i<endTrim;i++) { trim_time = ssd.event_arrive(READ, i, 1, ((start_time+arrive_time)*timeMultiplier)); avgsRead3.push_back(trim_time); num_trims++; arrive_time += trim_time; if (i % 1000 == 0) printf("Read: %i %f\n", i, trim_time); } /* Test 1 */ for (int i=startTrim; i<endTrim;i++) { trim_time = ssd.event_arrive(TRIM, i, 1, ((start_time+arrive_time)*timeMultiplier)); avgsTrim2.push_back(trim_time); num_trims++; arrive_time += trim_time; if (trim_time > 400) printf("Trim: %i %f\n", i, trim_time); } for (int i=startTrim; i<endTrim;i++) { trim_time = ssd.event_arrive(WRITE, i, 1, ((start_time+arrive_time)*timeMultiplier)); avgsWrite2.push_back(trim_time); num_trims++; arrive_time += trim_time; if (i % 1000 == 0) printf("Write: %i %f\n", i, trim_time); } for (int i=startTrim; i<endTrim;i++) { trim_time = ssd.event_arrive(READ, i, 1, ((start_time+arrive_time)*timeMultiplier)); avgsRead4.push_back(trim_time); num_trims++; arrive_time += trim_time; if (i % 1000 == 0) printf("Read: %i %f\n", i, trim_time); } // // 1. Write random to the size of the device // for (int i=0; i<700000;i++) // { // long int r = (random()%preIO-200000)+200000; // double d = ssd.event_arrive(WRITE, r, 1, afterFormatStartTime); // afterFormatStartTime += d; // // if (i % 10000 == 0) // printf("Wrote %i %f\n", i,d ); // } // // for (int i=startTrim; i<endTrim;i++) // { // // trim_time = ssd.event_arrive(WRITE, i, 1, ((start_time+arrive_time)*timeMultiplier)); // avgsWrite3.push_back(trim_time); // num_trims++; // // arrive_time += trim_time; // // if (i % 1000 == 0) // printf("Write: %i %f\n", i, trim_time); // // } ssd.print_ftl_statistics(); FILE *logFile = NULL; if ((logFile = fopen("output.log", "w")) == NULL) { printf("Output file cannot be written to.\n"); exit(-1); } fprintf(logFile, "Trim;Read1;Read2;Write1;Read3;Trim2;Write2;Read4;Write3\n"); for (size_t i=0;i<avgsTrim.size();i++) { fprintf(logFile, "%f;%f;%f;%f;%f;%f;%f;%f\n", avgsTrim[i],avgsRead1[i], avgsRead2[i], avgsWrite1[i], avgsRead3[i], avgsTrim2[i], avgsWrite2[i], avgsRead4[i]); } fclose(logFile); ssd.print_ftl_statistics(); ssd.print_statistics(); printf("Finished.\n"); return 0; }
int main(int argc, char **argv) { char read_file_name[100] = ""; char write_file_name[100] = ""; std::set<unsigned int> addresses; FILE *read_file; FILE *write_file; double initial_delay; unsigned int q_depth; bool write_data; //unsigned int req_per_thread = 1000; unsigned int total_read_count = 10000000, cur_read_count = 0; load_config(); print_config(NULL); printf("\n"); Ssd *ssd = new Ssd(); srand(10111); unsigned int write = atoi(argv[1]); unsigned int util_percent = atoi(argv[2]); q_depth = atoi(argv[3]); //total_read_count = q_depth * 10000; char ftl_implementation[10] = {'0' + FTL_IMPLEMENTATION}; char gc_scheme[10] = {'0' + GC_SCHEME}; printf("addressable blocks %d\n", NUMBER_OF_ADDRESSABLE_BLOCKS); unsigned int lastLBA = NUMBER_OF_ADDRESSABLE_BLOCKS * BLOCK_SIZE; strcat(read_file_name, "closed_read_"); strcat(read_file_name, ftl_implementation); strcat(read_file_name, "_"); strcat(read_file_name, gc_scheme); strcat(read_file_name, "_"); strcat(read_file_name, argv[1]); strcat(read_file_name, "_"); strcat(read_file_name, argv[2]); strcat(read_file_name, "_"); strcat(read_file_name, argv[3]); strcat(read_file_name, ".out"); strcat(write_file_name, "closed_write_"); strcat(write_file_name, ftl_implementation); strcat(write_file_name, "_"); strcat(write_file_name, gc_scheme); strcat(write_file_name, "_"); strcat(write_file_name, argv[1]); strcat(write_file_name, "_"); strcat(write_file_name, argv[2]); strcat(write_file_name, "_"); strcat(write_file_name, argv[3]); strcat(write_file_name, ".out"); read_file = fopen(read_file_name, "w"); write_file = fopen(write_file_name, "w"); bool noop_complete = false; double next_noop_time = 0; double prev_noop_time = 0; bool write_complete = false; double write_end_time = 0; unsigned int occupied = util_percent*lastLBA/100; unsigned int i=0; for (i = 0; i < occupied; i++) { write_complete = false; bool result = ssd -> event_arrive(WRITE, i%lastLBA, 1, write_end_time, write_complete, write_end_time); if(result == false) { printf("returning failure\n"); return -1; } //printf("Write %d %f\n", write_complete, write_end_time); prev_noop_time = write_end_time; int k = 0; while(!write_complete) { ssd->event_arrive(NOOP, 1, 1, prev_noop_time, noop_complete, next_noop_time); prev_noop_time = next_noop_time; k++; } addresses.insert(i); } initial_delay = write_end_time; printf("Completed\n"); fflush(stdout); if(write == 0) { write_data = false; } else { write_data = true; q_depth = 2*q_depth; } printf("starting experiment\n"); fflush(stdout); unsigned int count[q_depth]; bool op_complete[q_depth]; double op_start_time[q_depth]; double op_complete_time[q_depth]; unsigned int op_addresses[q_depth]; for (unsigned int i=0;i<q_depth;i++) { count[i] = 0; op_complete[i] = false; op_start_time[i] = initial_delay; op_addresses[i] = 0; } next_noop_time = initial_delay; unsigned int location = 0; unsigned int write_count = 0; bool loop = true; for(unsigned int i=0;i<q_depth;i++) { bool result; if(write_data && i >= q_depth/2) { location = rand()%lastLBA; result = ssd->event_arrive(WRITE, location, 1, (double) op_start_time[i], op_complete[i], op_complete_time[i]); if(result == false) { fprintf(read_file, "==========\nCould not do a write, incomplete experiment\n"); goto exit; } op_addresses[i] = location; } else { location = rand()%lastLBA; while(addresses.find(location) == addresses.end()) { location = rand()%lastLBA; } result = ssd->event_arrive(READ, location, 1, (double) op_start_time[i], op_complete[i], op_complete_time[i]); if(result == -1) { fprintf(read_file, "==========\nCould not do a read, incomplete experiment\n"); goto exit; } } } prev_noop_time = initial_delay; while(loop) { bool event_completed = false; unsigned int loop_c = 0; double earliest_event = -1; unsigned int earliest_event_index = 0; for(unsigned int i=0;i<q_depth;i++) { //printf("%d %p %d %f %f\n", i, &op_complete[i], op_complete[i], op_complete_time[i], earliest_event); if(op_complete[i]) { event_completed = true; if(op_complete_time[i] < earliest_event || earliest_event == -1) { earliest_event = op_complete_time[i]; earliest_event_index = i; } } } if(event_completed) prev_noop_time = earliest_event < prev_noop_time ? earliest_event : prev_noop_time; while(!event_completed) { ssd->event_arrive(NOOP, 1, 1, prev_noop_time, noop_complete, next_noop_time); prev_noop_time = next_noop_time; for(unsigned int i=0;i<q_depth;i++) { printf("%d %d %f %f\n", i, op_complete[i], op_complete_time[i], earliest_event); if(op_complete[i]) { event_completed = true; if(op_complete_time[i] < earliest_event || earliest_event == -1) { earliest_event = op_complete_time[i]; earliest_event_index = i; } } } if(event_completed) prev_noop_time = earliest_event < prev_noop_time ? earliest_event : prev_noop_time; else prev_noop_time = next_noop_time; loop_c++; } //for(unsigned int i=0;i<q_depth;i++) //{ //printf("op complete %d %d\n", i, op_complete[i]); //if(op_complete[i]) //{ bool result = false; op_complete[earliest_event_index] = false; //printf("Earliest event index %d earliest event time %f\n", earliest_event_index, earliest_event); if(write_data && earliest_event_index >= q_depth/2) { count[earliest_event_index]++; addresses.insert(op_addresses[earliest_event_index]); fprintf(write_file, "%.5lf\t%.5lf\t%.5lf\n", op_start_time[earliest_event_index], op_complete_time[earliest_event_index] - op_start_time[earliest_event_index], op_complete_time[earliest_event_index]); write_count++; op_start_time[earliest_event_index] = op_complete_time[earliest_event_index]; location = rand()%lastLBA; op_addresses[earliest_event_index] = location; result = ssd->event_arrive(WRITE, location, 1, (double) op_start_time[earliest_event_index], op_complete[earliest_event_index], op_complete_time[earliest_event_index]); if(result == false) { fprintf(read_file, "==========\nCould not do a write, incomplete experiment\n"); goto exit; } } else { fprintf(read_file, "%.5lf\t%.5lf\t%.5lf\n", op_start_time[earliest_event_index], op_complete_time[earliest_event_index] - op_start_time[earliest_event_index], op_complete_time[earliest_event_index]); count[earliest_event_index]++; op_start_time[earliest_event_index] = op_complete_time[earliest_event_index]; location = rand()%lastLBA; while(addresses.find(location) == addresses.end()) { location = rand()%lastLBA; } cur_read_count++; op_addresses[earliest_event_index] = location; result = ssd->event_arrive(READ, location, 1, (double) op_start_time[earliest_event_index], op_complete[earliest_event_index], op_complete_time[earliest_event_index]); if(result == false) { fprintf(read_file, "==========\nCould not do a read, incomplete experiment\n"); goto exit; } } //prev_noop_time = op_complete_time[i] < prev_noop_time ? op_complete_time[i] : prev_noop_time; //} //} if(cur_read_count >= total_read_count) { loop = false; break; } } exit: fprintf(stdout, "========================\n"); fprintf(stdout, "experiment ended with write_count as %d\n", write_count); ssd->print_ftl_statistics(stdout); fclose(read_file); fclose(write_file); delete ssd; return 0; }