Skip to content

Commit ad5ed0d

Browse files
Fixing up the last loose ends. :)
Adding verification and bimodal tests.
1 parent 8fe6947 commit ad5ed0d

17 files changed

+2738
-111
lines changed

.cproject

Lines changed: 1960 additions & 6 deletions
Large diffs are not rendered by default.

FTLs/bast_ftl.cpp

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,12 @@ enum status FtlImpl_Bast::write(Event &event)
151151
uint numValid = controller.get_num_valid(&logBlock->address);
152152
if (numValid < BLOCK_SIZE)
153153
{
154+
if (logBlock->pages[eventAddress.page] != -1)
155+
{
156+
Address replace_address = Address(logBlock->address.get_linear_address()+logBlock->pages[eventAddress.page], PAGE);
157+
event.set_replace_address(replace_address);
158+
}
159+
154160
logBlock->pages[eventAddress.page] = numValid;
155161

156162
Address logBlockAddress = logBlock->address;
@@ -163,15 +169,22 @@ enum status FtlImpl_Bast::write(Event &event)
163169

164170
allocate_new_logblock(logBlock, lba, event);
165171
logBlock = log_map[lba];
166-
//printf("Using new log block with address: %lu Block: %u\n", logBlock->address.get_linear_address(), logBlock->address.block);
167172
// Write the current io to a new block.
168173
logBlock->pages[eventAddress.page] = 0;
169174
Address dataPage = logBlock->address;
170175
dataPage.valid = PAGE;
171176
event.set_address(dataPage);
177+
172178
}
173179

174-
Block_manager::instance()->insert_events(event);
180+
if (data_list[lba] != -1)
181+
{
182+
183+
int offset = event.get_logical_address() % BLOCK_SIZE;
184+
Address replace = new Address(data_list[lba]+offset, PAGE);
185+
if (controller.get_block_pointer(replace)->get_state(offset) != EMPTY)
186+
event.set_replace_address(replace);
187+
}
175188

176189
// Statistics
177190
controller.stats.numFTLWrite++;
@@ -226,8 +239,6 @@ enum status FtlImpl_Bast::trim(Event &event)
226239
event.set_address(returnAddress);
227240
event.set_noop(true);
228241

229-
Block_manager::instance()->insert_events(event);
230-
231242
// Statistics
232243
controller.stats.numFTLTrim++;
233244

@@ -239,7 +250,6 @@ void FtlImpl_Bast::allocate_new_logblock(LogPageBlock *logBlock, long lba, Event
239250
{
240251
if (log_map.size() >= BAST_LOG_PAGE_LIMIT)
241252
{
242-
srandom(10);
243253
int victim = random()%log_map.size()-1;
244254
std::map<long, LogPageBlock*>::iterator it = log_map.begin();
245255

@@ -319,28 +329,34 @@ bool FtlImpl_Bast::random_merge(LogPageBlock *logBlock, long lba, Event &event)
319329
Address eventAddress = Address(event.get_logical_address(), PAGE);
320330
Address newDataBlock = Block_manager::instance()->get_free_block(DATA, event);
321331

332+
Block *b1 = controller.get_block_pointer(logBlock->address);
333+
334+
int t=0;
322335
for (uint i=0;i<BLOCK_SIZE;i++)
323336
{
324337
// Lookup page table and see if page exist in log page
325338
Address readAddress;
326-
if (logBlock->pages[eventAddress.page] != -1 && logBlock->pages[i] != -1)
327-
readAddress.set_linear_address(logBlock->address.real_address + logBlock->pages[i], PAGE);
339+
if (logBlock->pages[i] != -1)
340+
readAddress.set_linear_address(logBlock->address.get_linear_address() + logBlock->pages[i], PAGE);
328341
else if (data_list[lba] != -1)
329342
readAddress.set_linear_address(data_list[lba] + i, PAGE);
330343
else
331344
continue; // Empty page
332345

346+
if (controller.get_state(readAddress) == EMPTY)
347+
continue;
348+
333349
if (controller.get_state(readAddress) == INVALID) // A page might be invalidated by trim
334350
continue;
335351

336352
Event readEvent = Event(READ, event.get_logical_address(), 1, event.get_start_time());
337353
readEvent.set_address(readAddress);
338354
controller.issue(readEvent);
339-
//event.consolidate_metaevent(readEvent);
340355

341356
Event writeEvent = Event(WRITE, event.get_logical_address(), 1, event.get_start_time()+readEvent.get_time_taken());
342357
writeEvent.set_address(Address(newDataBlock.get_linear_address() + i, PAGE));
343358
writeEvent.set_payload((char*)page_data + readAddress.get_linear_address() * PAGE_SIZE);
359+
writeEvent.set_replace_address(readAddress);
344360
controller.issue(writeEvent);
345361

346362
//event.consolidate_metaevent(writeEvent);
@@ -350,22 +366,26 @@ bool FtlImpl_Bast::random_merge(LogPageBlock *logBlock, long lba, Event &event)
350366
controller.stats.numFTLWrite++;
351367
controller.stats.numWLRead++;
352368
controller.stats.numWLWrite++;
369+
t++;
353370
}
354371

372+
// printf("t %i\n",t);
373+
355374
// Invalidate inactive pages (LOG and DATA
375+
356376
Block_manager::instance()->erase_and_invalidate(event, logBlock->address, LOG);
377+
357378
if (data_list[lba] != -1)
358379
{
359380
Address a = Address(data_list[lba], PAGE);
381+
Block *b2 = controller.get_block_pointer(a);
360382
Block_manager::instance()->erase_and_invalidate(event, a, DATA);
361383
}
362384

363-
364385
// Update mapping
365386
data_list[lba] = newDataBlock.get_linear_address();
366387
update_map_block(event);
367388

368-
369389
dispose_logblock(logBlock, lba);
370390

371391
controller.stats.numLogMergeFull++;

FTLs/bdftl_ftl.cpp

Lines changed: 52 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,6 @@ enum status FtlImpl_BDftl::read(Event &event)
8787
} else { // DFTL lookup
8888
resolve_mapping(event, false);
8989

90-
//MpageByID::iterator it = trans_map.find(dlpn);
91-
//MpageByID::iterator it = trans_map[dlpn];
92-
//MPage current = *it;
9390
MPage current = trans_map[dlpn];
9491

9592
if (current.ppn != -1)
@@ -162,18 +159,20 @@ enum status FtlImpl_BDftl::write(Event &event)
162159

163160
MPage current = trans_map[startAdr + i];
164161

165-
assert(current.ppn == -1);
162+
if (current.ppn != -1)
163+
{
164+
update_translation_map(current, block_map[dlbn].pbn+i);
165+
current.create_ts = event.get_start_time();
166+
current.modified_ts = event.get_start_time();
167+
current.cached = true;
168+
trans_map.replace(trans_map.begin()+startAdr+i, current);
166169

167-
update_translation_map(current, block_map[dlbn].pbn+i);
168-
current.create_ts = event.get_start_time();
169-
current.modified_ts = event.get_start_time();
170-
current.cached = true;
171-
trans_map.replace(trans_map.begin()+startAdr+i, current);
170+
cmt++;
172171

173-
cmt++;
172+
event.incr_time_taken(RAM_WRITE_DELAY);
173+
controller.stats.numMemoryWrite++;
174+
}
174175

175-
event.incr_time_taken(RAM_WRITE_DELAY);
176-
controller.stats.numMemoryWrite++;
177176
}
178177

179178
// 4. Set block to non optimal
@@ -281,7 +280,7 @@ enum status FtlImpl_BDftl::trim(Event &event)
281280
// Block-level lookup
282281
if (block_map[dlbn].optimal)
283282
{
284-
Address address = Address(block_map[dlbn].pbn, PAGE);
283+
Address address = Address(block_map[dlbn].pbn+event.get_logical_address()%BLOCK_SIZE, PAGE);
285284
Block *block = controller.get_block_pointer(address);
286285
block->invalidate_page(address.page);
287286

@@ -293,47 +292,42 @@ enum status FtlImpl_BDftl::trim(Event &event)
293292
}
294293
} else { // DFTL lookup
295294

296-
resolve_mapping(event, false);
297-
298295
MPage current = trans_map[dlpn];
299296
if (current.ppn != -1)
300297
{
301298
Address address = Address(current.ppn, PAGE);
302299
Block *block = controller.get_block_pointer(address);
303300
block->invalidate_page(address.page);
304301

302+
evict_specific_page_from_cache(event, dlpn);
303+
305304
// Update translation map to default values.
306305
update_translation_map(current, -1);
307-
current.modified_ts = -1;
308-
current.cached = false;
309306
trans_map.replace(trans_map.begin()+dlpn, current);
310307

311-
// Remove it from cache too.
312-
cmt--;
313-
314308
event.incr_time_taken(RAM_READ_DELAY);
315309
event.incr_time_taken(RAM_WRITE_DELAY);
316310
controller.stats.numMemoryRead++;
317311
controller.stats.numMemoryWrite++;
312+
}
318313

319-
// Update trim map and update block map if all pages are trimmed. i.e. the state are reseted to optimal.
320-
long addressStart = dlpn - dlpn % BLOCK_SIZE;
321-
bool allTrimmed = true;
322-
for (uint i=addressStart;i<addressStart+BLOCK_SIZE;i++)
323-
{
324-
if (!trim_map[i])
325-
allTrimmed = false;
326-
}
314+
// Update trim map and update block map if all pages are trimmed. i.e. the state are reseted to optimal.
315+
long addressStart = dlpn - dlpn % BLOCK_SIZE;
316+
bool allTrimmed = true;
317+
for (uint i=addressStart;i<addressStart+BLOCK_SIZE;i++)
318+
{
319+
if (!trim_map[i])
320+
allTrimmed = false;
321+
}
327322

328-
controller.stats.numMemoryRead++; // Trim map looping
323+
controller.stats.numMemoryRead++; // Trim map looping
329324

330-
if (allTrimmed)
331-
{
332-
block_map[dlbn].pbn = -1;
333-
block_map[dlbn].nextPage = 0;
334-
block_map[dlbn].optimal = true;
335-
controller.stats.numMemoryWrite++; // Update block_map.
336-
}
325+
if (allTrimmed)
326+
{
327+
block_map[dlbn].pbn = -1;
328+
block_map[dlbn].nextPage = 0;
329+
block_map[dlbn].optimal = true;
330+
controller.stats.numMemoryWrite++; // Update block_map.
337331
}
338332
}
339333

@@ -442,3 +436,25 @@ bool FtlImpl_BDftl::block_next_new()
442436
return (currentDataPage == -1 || currentDataPage % BLOCK_SIZE == BLOCK_SIZE -1);
443437
}
444438

439+
void FtlImpl_BDftl::print_ftl_statistics()
440+
{
441+
int size = SSD_SIZE * PACKAGE_SIZE * DIE_SIZE * PLANE_SIZE;
442+
443+
printf("FTL Stats:\n");
444+
printf(" Blocks total: %i\n", size);
445+
446+
int numOptimal = 0;
447+
for (int i=0;i<size;i++)
448+
{
449+
BPage bp = block_map[i];
450+
if (bp.optimal)
451+
{
452+
printf("Optimal: %i\n", i);
453+
numOptimal++;
454+
}
455+
456+
}
457+
458+
printf(" Blocks optimal: %i\n", numOptimal);
459+
}
460+

FTLs/dftl_ftl.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,6 @@ enum status FtlImpl_Dftl::trim(Event &event)
105105
{
106106
uint dlpn = event.get_logical_address();
107107

108-
resolve_mapping(event, false);
109-
110108
event.set_address(Address(0, PAGE));
111109

112110
MPage current = trans_map[dlpn];
@@ -117,9 +115,9 @@ enum status FtlImpl_Dftl::trim(Event &event)
117115
Block *block = controller.get_block_pointer(address);
118116
block->invalidate_page(address.page);
119117

118+
evict_specific_page_from_cache(event, dlpn);
119+
120120
update_translation_map(current, -1);
121-
current.modified_ts = -1;
122-
current.create_ts = -1;
123121

124122
trans_map.replace(trans_map.begin()+dlpn, current);
125123
}

FTLs/dftl_parent.cpp

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -171,41 +171,20 @@ void FtlImpl_DftlParent::resolve_mapping(Event &event, bool isWrite)
171171

172172
MPage current = trans_map[dlpn];
173173
current.modified_ts = event.get_start_time();
174+
if (isWrite)
175+
current.modified_ts++;
174176
current.create_ts = event.get_start_time();
175177
current.cached = true;
176178
trans_map.replace(trans_map.begin()+dlpn, current);
177179

178-
// MpageByModified::iterator iter = boost::multi_index::get<1>(trans_map).begin();
179-
// printf("--------\n");
180-
// for (int i=0;i<5;i++)
181-
// {
182-
// printf("@@@ %i %i %f %f %i\n", (*iter).vpn, (*iter).ppn , (*iter).create_ts, (*iter).modified_ts, (*iter).cached);
183-
// ++iter;
184-
// }
185-
//
186-
// MpageByModified::iterator iterE = boost::multi_index::get<1>(trans_map).end();
187-
//
188-
// for (int i=0;i<20;i++)
189-
// {
190-
// --iterE;
191-
// printf("$$$ %i %i %f %f %i\n", (*iterE).vpn, (*iterE).ppn , (*iterE).create_ts, (*iterE).modified_ts, (*iterE).cached);
192-
//
193-
// }
194-
195180
cmt++;
196-
197-
198181
}
199182
}
200183

201184
void FtlImpl_DftlParent::evict_page_from_cache(Event &event)
202185
{
203-
int x = 0;
204-
int y = 0;
205-
206186
while (cmt >= totalCMTentries)
207187
{
208-
x++;
209188
// Find page to evict
210189
MpageByModified::iterator evictit = boost::multi_index::get<1>(trans_map).begin();
211190
MPage evictPage = *evictit;
@@ -239,7 +218,6 @@ void FtlImpl_DftlParent::evict_page_from_cache(Event &event)
239218
event.incr_time_taken(write_event.get_time_taken());
240219
controller.stats.numFTLWrite++;
241220
controller.stats.numGCWrite++;
242-
y++;
243221
}
244222

245223
// Remove page from cache.
@@ -249,7 +227,54 @@ void FtlImpl_DftlParent::evict_page_from_cache(Event &event)
249227
reset_MPage(evictPage);
250228
trans_map.replace(trans_map.begin()+evictPage.vpn, evictPage);
251229
}
252-
//printf("%i %i %i \n", cmt,x , y);
230+
}
231+
232+
void FtlImpl_DftlParent::evict_specific_page_from_cache(Event &event, long lba)
233+
{
234+
// Find page to evict
235+
MPage evictPage = trans_map[lba];
236+
237+
if (!evictPage.cached)
238+
return;
239+
240+
assert(evictPage.cached && evictPage.create_ts >= 0 && evictPage.modified_ts >= 0);
241+
242+
if (evictPage.create_ts != evictPage.modified_ts)
243+
{
244+
// Evict page
245+
// Inform the ssd model that it should invalidate the previous page.
246+
// Calculate the start address of the translation page.
247+
int vpnBase = evictPage.vpn - evictPage.vpn % addressPerPage;
248+
249+
for (int i=0;i<addressPerPage;i++)
250+
{
251+
MPage cur = trans_map[vpnBase+i];
252+
if (cur.cached)
253+
{
254+
cur.create_ts = cur.modified_ts;
255+
trans_map.replace(trans_map.begin()+vpnBase+i, cur);
256+
}
257+
}
258+
259+
// Simulate the write to translate page
260+
Event write_event = Event(WRITE, event.get_logical_address(), 1, event.get_start_time());
261+
write_event.set_address(Address(0, PAGE));
262+
write_event.set_noop(true);
263+
264+
if (controller.issue(write_event) == FAILURE) { assert(false);}
265+
266+
event.incr_time_taken(write_event.get_time_taken());
267+
controller.stats.numFTLWrite++;
268+
controller.stats.numGCWrite++;
269+
}
270+
271+
// Remove page from cache.
272+
cmt--;
273+
274+
evictPage.cached = false;
275+
reset_MPage(evictPage);
276+
trans_map.replace(trans_map.begin()+evictPage.vpn, evictPage);
277+
253278
}
254279

255280
void FtlImpl_DftlParent::update_translation_map(FtlImpl_DftlParent::MPage &mpage, long ppn)

0 commit comments

Comments
 (0)