4. OpenSSD greedy FTL을 miss FTL로의 변환 (프로젝트)

이번에 연구실에서 한 프로젝트는 open SSD jasmine을 가지고 ftl을 수정하는 것이었다. 목표는 read, write과정에서 SDRAM에 저장되어 있는 mapping table을 참고하지 않고 flash에 있는 mapping 정보를 참조하는 것이었다. 우리는 이 ftl을 miss FTL이라고 명명했고 원래의 ftl인 greedy FTL과 퍼포먼스를 비교하였다.

miss FTL은 mapping table을 SDRAM이 아닌 Flash로부터 읽어오고, 수정할 것이므로 퍼포먼스가 현저히 떨어질거라 예측할 수 있었다. 그러나, miss FTL은 비싼 SDRAM에 의존하지 않을 수 있다는 장점이 있다. flash 의 용량이 커질수록 그에 따르는 mapping table의 크기도 커지며 따라서 SDRAM의 가격이 기하급수적으로 증가한다는 문제점이 있다. 따라서 대용량의 SSD를 쓰는 사람의 경우 miss FTL을 사용하면 퍼포먼스는 줄어들겠지만 SDRAM에 가격을 투자하지 않아도 되서 가격이 저렴해 질 것이다.

greedy FTL 은 다음과 같은 방식으로 SDRAM에 있는 mapping table을 참고한다.
그림1. greedy FTL mapping table

우리가 만든 miss FTL은 다음과 같은 방식으로 flash 에 있는 mapping table을 참고한다.


그림2. miss FTL mapping table




















이 과정에서 우리가 주목한 것은 ftl 내에 있는 ftl_read(), ftl_write()함수였다. 함수내에는 get_vpn(), set_vpn()함수가 존재하여 mapping table에 대한 read, write를 담당하였다.


우선적으로 기본적인 SSD에 들어갈 코드를 http://csl.skku.edu/uploads/ICE3028S14/OpenSSD-1.1.1.zip에서 다운로드받았다. 해당 코드에는 ftl_logblock, ftl_tutorial, ftl_greedy, gtl_faster등 여러 ftl 이 있었는데, 우리는 greedy FTL을 사용하기로 결정했다.

1. greedy FTL - ftl_read()

HOST는 SSD를 하드디스크로 인지하고, 그에 맞게  read/write 요청을 수행한다. host가 read할때 요청하는 주소는 LBN(logical block address) 와 num_sector(size)이다. 함수 내에서는 이 주소를 이용하여 다음과 같은 연산수행을 거친다.



그림3 greedy FTL read
가장 먼지 FTL은 HOST 의 명령을 page단위의 주소 및 offset으로 수정한다. 이는 FTL내에서 read/write의 한 단위가 page 이기 때문이다.

그림4 greedy FTL read
get_vpn() 은 참 중요한 함수이다. 이 함수는 SDRAM에 저장되어 있는 mapping table을 참조하여 실제 주소(virtual address)를 받아 vpn에 저장한다.

다음으로 그림과 같이 lpn은 순차적으로 bank에 대응되어 있기 때문에 physical bank를 구하는 일은 어렵지 않다.


그림5 greedy FTL read


이렇게 bank, vpn을 받아오면, ftl은 LLD(low-level device driver)에게 read명령을 내린다. LLD내에서는 FCP의 래지스터를 설정하고 issue시켜 WR(waiting room)에 보낸다. WR에서는 우리가 알듯이 read할 bank가 busy하지 않기를 기다려 실제 명령을 수행한다. (이후 내용은 BSP에 저장되겠지??)


2. miss FTL-ftl_read

우리가 작성할 miss FTL에서는 read를 할때 SDRAM에 있는 mapping table이 아닌 Flash에 저장되어 있는 mapping table로 부터 맵핑정보를 읽어오고자 하였다. 다른 부분은 greedy와 같기 때문에, 우리가 손을 델 부분은 get_vpn() 이었다.

주목하자. 원래 mapping table은 SSD를 부팅시 flash로부터 가져오게 되있다. 다시말해 SDRAM에 있는 mapping table은 원래 flash내에 존재한다. 우리가 할 일은 이 위치를 찾는 것이었다. 해당 위치는 load_pmap_table 함수를 통해 알 수 있었다. load_pmap_table은 ssd를 부팅할때 flash 로부터 mapping tabled을 SDRAM으로 로드하는 함수이다. 이를 통해 알수 있었던 SDRAM의 mapping table의 구조와 flash내의 mapping table의 구조는 다음과 같이 할당되어있다..

그림6 miss FTL - getVPN

여기에 대한 자세한 설명은 개념면에서 크게 중요하지 않아 생략한다. 우리가 수정한 코드는, lpn으로 부터 맵핑되어 있을 SDRAM내 mapping table주소가 원래는 flash 어느 위치에 존재하는 가를 파악하여, 해당 flash 로부터 읽어오는 일이었다.


3. greedy FTL - ftl_write

ftl_write역시 ftl_read와 크게 다르지 않은 모습을 보인다. read할때와 마찬가지로 HOST는 SSD를 하드디스크로 인지하고 요청을 보내며, read 와 유사한 방식으로 write를 한다.

다만 우리가 주목할 점은 write의 방식은 read에 비해 복잡하다는 것이다. 저번에 본 SATA write buffer그림을 살펴보자.


그림 7. 출처  <The Jasmine OpenSSD Platform>
우리의 greedy FTL은 그림과 같은 방식으로 write를 수행한다. SDRAM 에 존재하는 FTL_BUF라는 버퍼를 매개로 데이터를 이동시키는데 이동시키는 방법은 다음과 같다.

1. HOST로부터 SATA write buffer 에 데이터가 저장된다.
2. flash내의 원래 저장되어 있는 데이터를 페이지로 FTL_BUF에 읽어온다.
3. FTL_BUF내의 데이터에서 SATA write buffer의 비어있는 양쪽부분만큼만 데이터를 읽어서 SATA write buffer에 저장한다.
4. flash 내 emtpy한 page를 할당하여 SATA write buffer을 저장한다.

즉, greedy FTL은 write 를 할때마다 새로운 page를 할당하여 해당 장소에 write하게 된다. 그러므로 mapping table 은 계속해서 새롭게 수정해줘야하는데 set_vpn함수가 이 기능을 수행한다.

다시말해, write함수에서는 mapping table로부터 읽어오기 위한 get_vpn, mapping table에 다시 write하기 위한 set_vpn함수가 존재한다.

4. miss FTL - ftl_write

따라서 우리가 miss FTL의 write을 위해 주목해야할 점은 set_vpn 이었다. 우리는 write가 일어날때마다 SDRAM이 아닌 FLASH내에 접근하여 mapping table을 새롭게 수정해줘야하기 때문이었다. 이를 위해 우리는 flash 내의 mapping table이 어떤식으로 업데이트되어야 하는지 참고해야 했으며 해당 함수는 logging_pmap_table() 이 수행하였다. logging_pmap_table은 SDRAM에 있는 모든 mapping table을 flash에 업데이트하는 함수이다.


5. 실험

우리는 fio밴치마크를 이용해 greedy FTL 과 miss FTL의 퍼포먼스를 비교하였다. 해당 실험은 다음과 같은 결과를 이끌었다.

그림 8. greedy FTL , miss FTL 퍼포먼스 실험 결과




그림 9. greedy FTL , miss FTL 퍼포먼스 실험 결과 그래프


우리는 실험결과 read, write에서 miss FTL보다 greedy FTL의 퍼포먼스가 2~3배 더 빨라짐을 알 수 있었다. 실험의 정확성을 위해 2가지 방향에서 결과를 분석하였다.

1. 정확성 : 우리는 실험의 정확성을 위해 다음과 같은 조사를 하였다. 데이터를 write하고 그 자리에 있는 data를 다시 read 하여, write한 데이터와 read한 데이터가 서로 같은지를 연속적으로 비교하여 올바른 위치에 data가 read/ write됨을 확인할 수 있었다.

2. 속도 :
read를 할 때에는 가장 큰 bottle neck 구간은 flash로 부터 read를 하는 구간이다. greedy FTL에서는 flash 로부터의 read 를 1회 수행하나, miss FTL은 mapping table을 flash로 부터 읽으므로 2회 수행한다. 따라서 2배정도는 속도차이가 나야 정상이다.

write를 할때에 가장 큰 bottle neck 구간은 flash 에 write를 하는 구간이다. greedy FTL에서는 flash의 write를 1회 수행하나, missFTL에서는 mapping table을 flash에 다시 수정하므로 2회 수행한다. 따라서 속도가 2배는 차이나야 정상이다.

우리의 수행결과는 2~3배 차이났으므로 의미있는 결과가 나왔음을 확인할 수 있다.


6. 환경 설정

초반부 한번도 다뤄보지 못한 jasmine을 다루고 환경을 설정함에는 연구실 석사님이 많은 도움을 주셨다. 우리는 윈도우7으로 돌리려다 처참한 시간낭비를 맛보았기에 윈도우10으로 돌리기를 당부하고 강추한다.


1. 크로스 컴파일러


크로스컴파일러를 다운받고나서 관리자모드로 실행해야 한다.

2. PuTTy


보드에 올린 펌웨어의 동작을 확인하기 위해 사용한다. uart_printf를 통하여 펌웨어 코드에 대한 디버깅이 가능하다.

3. OpenSSD Technical Resources



OpenSSD 구조 및 개발 관련 레퍼런스 자료들이 저장되어있는 링크이다. 

4. OpenSSD Source download link


open SSD 의 greedy FTL등이 저장되어있는 펌웨어 소스코드이다.

5. Firmware installer


컴파일한 펌웨어를 보드에 올릴때 사용되는 프로그램이다.

6. FIO 밴치마크

우리는 fio 밴치마크를 이용하여 퍼포먼스를 분석하였다.


7. 마무리

방학동안 SSD를 이와같은 방식으로 공부하면서 많은 걸 체험하고 느끼고 배울 수 있었다. 우선적으로 연구실 교수님이랑 도와주신 조교님한테 감사하며, http://www.openssd-project.org/ 링크님에게도 감사를 드린다. 처음에 A Log Buffer-Based Flash Translation Layer Using Fully-Associative Sector Translation 논문으로 SSD의 감을 잡고, 프로젝트를 수행하는 과정에서 메뉴얼을 통해서 SSD의 구조를 이해하고 실제 SSD에 factoring 할 수 있었다. 이와 같은 방식으로 공부하면 SSD도 이제 어렵지 않아효! ㅂ2


















댓글

가장 많이 본 글