---
# System prepended metadata

title: Scalable Parallel Flash Firmware for Many-core Architectures

---

---
title: Scalable Parallel Flash Firmware for Many-core Architectures
tag : ssd
---
# Scalable Parallel Flash Firmware for Many-core Architectures

[paper](https://https://www.usenix.org/system/files/fast20-zhang_jie.pdf)

## introduction
* highly parallel I/O services require simultaneously performing many SSD internal tasks, the SSD needs multiple cores and parallel implementation for a higher throughput
* As the tasks inside the SSD increase, the SSD must address several scalability challenges brought by garbage collection, memory/storage contention and data consistency management when processing I/O requests in parallel. 
* We propose DeepFlash, a manycore-based NVMe SSD platform that can process more than one million I/O requests within a second (1MIOPS) while minimizing the requirements of internal resources
## Background
* a high-performance SSD architecture that Marvell recently published 
    * four Gen 3.0 PCIe lanes (4 GB/s)
    * three embedded processors, each employing two cores 
![](https://i.imgur.com/ppVTkIc.png)
#### Datapath from PCIe to flash
* Figure 2b shows the processes of the FTL, which performs the steps 3~8
![](https://i.imgur.com/OF9Tn8V.png)

## Challenges to Exceeding 1MIOPS
we extend the baseline SSD architecture in a highly scalable environment : Intel many-integrated cores (MIC) platform, which **provides a high core** count to study parallelism and scalability
### Flash scaling
* A single MIC core, which two threads are initialized to process the tasks of HIL and FTL
* 16 MIC cores (one core per flash channel) to manage flash interface subsystems
* Testing 4KB sequential writes
* Performance bottleneck
    * A single-core SSD controller is insufficient to fetch all the requests
    *  Faster to parallelize I/O accesses across many flash chips than performing address translation only on one core
![](https://i.imgur.com/sPFAxyT.png)
### Core scaling
* Naive can only achieve 813K IOPS even with 32 cores, which exhibits 82.6% lower performance, compared to Expected because **contention and consistency management for the memory spaces of internal DRAM** introduces significant synchronization overheads

## Many-to-Many Threading Firmware
### overview
* The queuegather stage mainly parses NVMe requests and collects them to the SSD-internal DRAM
* The trans-apply stage mainly buffers the data and translates addresses
* The flash scatter stage spreads the requests across many underlying flash packages and manages background SSD-internal tasks in parallel
![](https://i.imgur.com/YBUuyIi.png)
* While the procedure of I/O services is managed by many threads in the different data processing paths, the threads can be allocated in any core in the network, in a parallel and scalable manner.
![](https://i.imgur.com/vshj2kn.png)

### Queue-gather Stage
#### NVMe queue management
A host initiates an NVMe command to an SQ and writes the corresponding doorbell, the firmware **fetches the command from the SQ and decodes a non-contiguous set of host physical memory pages** by referring a kernel list structure, called a physical region page
* A challenge to employ many cores for parallel queue processing is that, multiple NVMQ cores may simultaneously fetch a same set of NVMe commands from a single queue(Fig.6(a))
* To address this challenge, one can make each core handle only a set of SQ/CQ(Fig.6(b))

![](https://i.imgur.com/BGfWEdJ.png)
#### I/O mutual exclusion.
* Request-1 (a write) and request-2 (a read), which create two different paths, but target to the same PPA. (Fig.6(c))
* We implement the **index lock as a redblack tree** and make this locking system as a dedicated thread (ILOCK). The red-black tree helps ILOCK quickly identify which lock to use, and reduces the overheads of lock acquisition and release
### Trans-apply Stage
#### Data caching and buffering
*  Incarnate SSD internal memory as a burst buffer by mapping LBAs to DRAM addresses 
*   CACHE threads are configured with a traditional direct-map cache
* Since all NVMQ threads possibly communicate with a CACHE thread for every I/O request, it can introduce extra latency imposed by passing messages among threads.(Fig.7(a))
![](https://i.imgur.com/W9ObsNr.png)
#### Parallel address translation
*  We allocate the FTL address translation to multiple threads. 
*  Address partitioning can make all TRANS threads operate in parallel without interference(Fig.7(b))
### Flash-scatter Stage
#### Background task scheduling
*  GCs can be performed in parallel by allocating separate core(s), referred to as BGC.
*  BGC(s) records the block numbers that have no more entries to write when TRANS threads process incoming I/O requests
*  BGC reclaims blocks and updates the mapping table at background
#### Journalling
* DeepFlash separates the journalling from TRANS and assigns it to a LOG thread
#### Parallel flash accesses
* FCMD
    * Compose flash transactions respecting flash interface timing
    * Schedule them across different flash resources over the flash physical layer(PHY)
![](https://i.imgur.com/xUak9IX.png)
## Optimizing DeepFlash
#### Parallel Processing for NVMe Queue
Dynamic I/O serialization(DIOS) decouples the fetching and parsing processes of NVMe queue entries
![](https://i.imgur.com/0rgQ264.png)
####  Index Lock Optimization
* When multiple NVMQ threads contend to acquire or release the same lock due to their same target address range, it can raise 
    * lock contention 
    * low resource utilization
* acquisition
    *  if the target LBA has a conflict. It then checks the red-black (RB) tree returns the owner ID for all lock acquisition requests.The NVMQ thread receives the ID of the owning NVMQ thread, and can **forward** the request there to be processe
   
* release
    * If the target address is already held by another NVMQ thread, the lock requester can be stalled until the corresponding I/O service is completed
    * It directly removes the target node without an SQ inference process. 
![](https://i.imgur.com/24rPy06.png)

#### Non-blocking Cache
Fig10(b)
* Add a direct path between NVMQ and TRANS threadsnd make NVMQ threads access CACHE threads only if there is data in CACHE
* We allocate direct-map table(s) in a shared memory space to accommodate the cache metadata so that NVMQ threads can lookup the cache metadata on their own
* However, this simple approach may introduce inconsistency. We add “**evicted LPN**” field in each map table entry
## Evaluation
#### Implementation platform
* MIC 5120D accelerator hat employs 60 lightweight in-order cores (4 hardware threads per core) 
* The host employs a Xeon 16-core processor and 256 GB DRAM
*  SSD platform(12 cores)
    *  DeepFlash
    *  BaseDeepFlash(not apply the optimization techniques)
    *  ManyLayered
    ![](https://i.imgur.com/ceo9Chj.png)

### Performance Analysis
* ManyLayered outperforms 750SSD and 4600SSD by 1.5× and 45%, on average
* BaseDeepFlash exhibits poor performance in cases that the request size is smaller than 24KB with random patterns, because threads in NVMQ/ILOCK keep tight inter-thread communications
* DeepFlash provides 4.8 GB/s and 4.5 GB/s bandwidth for reads and writes
* ManyLayered suffer from core/flash-level conflicts
* BaseDeepFlash suffer from lock/sync issues 
![](https://i.imgur.com/hmT7Y5s.png)
* DeepFlash can mostly activate 6.3 cores that run 25 threads to process I/O services in parallel
* Because although many cores contend to acquire ILOCK which makes more cores stay in idle, the burst buffer successfully overcomes the long write latency of the flash
* Figure 12e shows the active core decomposition of DeepFlash
    * Reads require 23% more Flash activities
    
![](https://i.imgur.com/xoQLUdj.png)
#### Server workload traces
* MPS generates multiple lock contentions, due to more small-size random accesses
* DeepFlash's performance is not as good under DDR workloads because FCMD utilization is lower than 56% due to the address patterns of DDR
![](https://i.imgur.com/AgogsyR.png)
### CPU, Energy and Power Analyses
#### CPU usage and different flashes
* When we increase the number of threads more, the performance gains start to diminish due to the overhead of exchanging many messages
* When 19 cores are employed, SLC, MLC, and TLC achieve the maximum bandwidths 

![](https://i.imgur.com/KmOCrjs.png)
#### Power/Energy
* DeepFlash with 12 cores consumes 29 W while this power consumption is higher than existing SSDs (20 ∼ 30W)
*  However, power-efficient manycores can be used to reduce the power of our prototype
#### Different CPUs
* Figure 14c compares the minimum number of cores that DeepFlash requires to achieve 1MIOPS for both reads and writes
* However, due to the complicated core logic , OoO-1.2G and OoO-2.4G consume 93% and 110% more power than IO-1G to achieve the same level of IOPS
### Performance Analysis of Optimization
#### NVMQ
* This implies that the host also requires more cores since the NVMe allocates a queue per host CPU core
![](https://i.imgur.com/1yYwK6w.png)
#### ILOCK
![](https://i.imgur.com/TxNlrrP.png)

#### CACHE
* Even with more CACHE threads, performance gains diminish due to communication overhead
* DeepFlash’s 2-Bypass,which employs the bypass technique (with only 2 threads), can be ideal as it requires fewer threads to achieve 1MIOPS
#### Background activities
*  Once NVMQ is in idle, LOG and BGC reactivate their work
![](https://i.imgur.com/b98CBEk.png)
#### STEADY-STATE performance
* Figure 17b shows the impact of on-demand garbage collection (FGC) and journalling (FLOG) on the performance of DeepFlash. The results are compared to the ideal performance of DeepFlash (Pristine), which has no GC and LOG activities

## Conclusion
Our emulation prototype on a manycore-integrated accelerator reveals that it simultaneously processes beyond 1MIOPS, while successfully hiding long latency imposed by internal flash media.






