SSD의 구조

Develicit
32 min readOct 12, 2019

--

  • 플래시 메모리를 기반으로 한 저장 매체
  • 비트들은 플로팅 게이트 트랜지스터로 구성된 셀에 저장
  • 모든 컴포넌트가 전기 장치이며, 기계 장치를 가지지 않음
  • 트랜지스터는 셀에 전자를 저장하면서 쓰기를 하게 됨
  • 매번 P/E 사이클마다 일부 전자가 오류로 인해 트랜지스터에 갇히게 됨
  • 갇힌 전자들이 쌓여서 일정 수준을 넘어서면, 그 셀은 사용 불가능한 상태가 됨

Solid-State
직역하면 “고체 상태”라는 의미지만 소체(트랜지스터)라는 의미도 있다.

구성요소

SSD는 크게 컨트롤러플래시 메모리 두 부분으로 구성된다.

우선 사용자의 요청은 호스트 인터페이스를 통해서 SSD에 전달된다. 그 후에는 컨트롤러의 프로세서가 플래시 컨트롤러로 정보를 전달한다.

SSD는 자체적으로 내장된 메모리를 가지는데, 일반적으로 이 메모리는 주소 매핑 정보를 저장하거나 캐시의 용도로 사용된다.

호스트 인터페이스는 SSD의 성능을 결정하는 중요한 요소라고 할 수 있다. 가장 일반적인 호스트 인터페이스 방식은 ATA(SATA)와 PCI Express(PCIe) 타입인데, SATA 3.0 인터페이스는 대략 6Gbit/s, 초당 550MB 정도의 데이터 전송 능력을 가지고 있다. PCIe 3.0 인터페이스는 레인당 8GT/s, 초당 1GB 정도의 데이터 전송 능력을 가지고 있다.

PCIe 3.0 인터페이스는 최소 1개 이상의 레인을 가지고 있는데, 4개의 레인을 가진 SSD는 SATA 3.0 인터페이스보다 8배 빠른 4GB/s의 전송 속도를 낼 수 있다. 엔터프라이즈급 SSD 중에서는 SAS(Serial Attached SCSI) 인터페이스를 가지고 있는 제품들도 있는데, 이들은 12Gbit/s의 전송 속도를 제공하지만 이 인터페이스를 사용하는 제품은 많지 않다.

인터리빙(interleaving)
SSD는 성능 향상을 위해서 호스트로부터 받은 요청을 여러 칩에 나눠 동시에 처리할 수 있다. 낸드 컨트롤러에 연결된 채널은 1개 이상의 낸드 플래시 메모리 칩과 연결되어 있으며, 하나의 낸드 플래시 메모리 칩은 1개 이상의 웨이로 구성되어 있다. 한 페이지 이상의 요청을 여러 채널의 각 웨이에 분산 저장할 경우 요청에 대한 처리가 동시에 이뤄지므로 전반적인 성능을 높일 수 있다.
인터리빙을 최대한 활용하기 위해서 채널과 웨이의 개수를 늘려 동시에 더 많은 데이터를 처리할 수 있다. 단일 낸드 플래시 메모리 칩 하나의 읽기와 쓰기 속도는 각각 40MB/s, 26MB/s에 불과하지만 여러 개의 플래시 메모리 칩을 병렬로 연결해 사용하면 최근 SSD와 같은 성능을 얻을 수 있다.

PCIe와 SAS 인터페이스는 SATA보다 빠르다
최근의 SSD는 일반적으로 SATA 3.0과 PCIe 3.0을 지원하고 있다. SAS는 일부 엔터프라이즈 모델에 장착되기는 하지만 일반적이지는 않다.
PCIe와 SAS가 SATA보다는 훨씬 뛰어난 전송 속도를 보이지만, 가격이 조금 더 비싸다.

구조

SSD의 물리적 구조

SSD는 기계적인 구동부가 전혀 없고, 오직 전기 신호로 움직이는 저장 매체다. 이런 이유로 가장 중요한 구성요소는 컨트롤러라고 할 수 있는데, 낸드 플래시 메모리에 데이터를 저장하고 관리하고 데이터를 읽는 것까지 모든 것을 관장하는 가장 핵심 부품이기 때문이다. 만약 컨트롤러의 성능이 좋지 않으면 아무리 SLC라도 안정성, 신뢰성, 성능 등이 모두 떨어진다.

낸드 플래시 메모리에서 가장 중요한 것은 데이터의 읽기와 쓰기, 지우기에서 사용되는 단위인 블록과 페이지다. 특히 페이지는 실질적인 데이터 저장의 최소(기본) 단위이기 때문에 반드시 알아야 한다.

블록과 페이지

블록은 낸드 플래시 메모리 칩 다수를 묶어 하나의 공간으로 사용한다. 그러므로 SSD의 저장 공간을 정의내리면 “블록과 페이지의 묶음”이라고 할 수 있다. 때문에 이를 추상적으로 나타내면 아래와 같은 구조를 가진다.

SSD의 구조를 HDD와 비교해서 생각해 보면 블록은 HDD의 트랙과, 페이지는 HDD의 섹터와 매칭시키면 된다. 데이터 저장의 최소 단위는 HDD에서는 섹터이고, SSD에서는 페이지이다.

SSD에서는 물리적인 섹터가 존재하지 않는다. 하지만 우리가 PC에서 사용하는 FAT, NTFS와 같은 파일 시스템과 그 위에서 작동하는 운영체제, 프로그램들은 대부분 섹터를 기반으로 해서 동작한다. 하지만 낸드 플래시 메모리에는 물리적인 섹터가 없다.

FTL(Flash Tranlation Layer: 플래시 변환 계층)

FTL의 이해

컴퓨터에서 사용되는 파일 시스템, 운영 체제와 이를 기반으로 하는 프로그램들은 HDD에서 사용하는 섹터를 기반으로 하고 있다. 하지만 SSD는 블록과 페이지를 기반으로 하는 저장 매체다. 즉, 원칙적으로는 우리가 사용하는 기존의 PC를 위한 파일 시스템과 운영체제는 구조적인 문제로 직접적으로 플래시 메모리를 사용할 수 없다.

이런 문제를 해결하기 위해서 SSD는 컨트롤러 단계에서 FTL이라는 컴포넌트를 사용해 물리적인 블록과 페이지 위에 논리적인 섹터 구조를 구현하는 방식을 사용한다. 이를 통해 기존의 섹터 기반의 파일 시스템, 운영체제, 프로그램들이 문제없이 SSD를 사용할 수 있게 만들어준다. 또한 이러한 플래시 변환 계층에는 낸드 플래시 메모리라는 소자의 특성에 맞춰 필요한 부가적인 다른 기능들(웨어 레벨링, GC 등)이 포함되어 있다.

FTL의 대략적인 구조

파일 시스템과 운영체제는 SSD를 사용할 때 낸드 플래시 메모리를 직접 다루는 것이 아니라, 일종의 미들웨어인 FTL을 중간에 두고 이와 통신하는 구조를 가지고 있다. 그 하위에서 필요한 작업은 모두 FTL과 플래시 장치 드라이버가 알아서 해 준다.

이는 우리가 사용하는 운영체제나 파일 시스템이 SSD의 물리적인 영역에 관여하지 않는다는 것을 말한다. 웨어 레벨링과 GC 등의 작업은 SSD 컨트롤러 자체에서 진행한다. 하지만 TRIM은 예외적으로 운영체제에서 지워진 파일에 대한 정보를 제공받는다.

FTL은 호스트의 LBA와 드라이브의 PBA를 매핑해주는 컨트롤러의 컴포넌트다. 가장 최근 드라이브는 Log Structure 파일 시스템과 함께 작동하는 “Hybrid Log-Blocking Mapping” 또는 그 파생 알고리즘을 구현하고 있다. 이 알고리즘은 랜덤 쓰기를 순차 쓰기처럼 핸들링 할 수 있도록 해준다.

주소 변환: FTL과 논리 주소, 물리 주소

시스템이 논리적인 섹터 주소를 통해 SSD의 데이터에 접근하면, FTL은 논리적인 섹터 주소를 물리적인 블록과 페이지 주소로 변환해 낸드 플래시 메모리의 페이지에 도달하게 된다. 이를 위해서 플래시 변환 계층은 논리 주소와 물리 주소를 연결해주는 주소 변환용 매핑 테이블을 가지고 있다. 즉, 파일 시스템의 논리 주소가 실제로 플래시 메모리의 물리 주소에 연결되는 것인지에 대한 테이블을 가지고 서로 연결시키게 된다.

FTL과 주소 변환, 웨어 레벨링 작업의 관계, GC

플래시 메모리의 셀은 P/E 사이클이 정해져 있고, 그에 따라서 정해진 수명이 있다. 또한 덮어쓰기 작업이 불가능하다. 때문에 특정 페이지에 집중된 쓰기 작업이 발생하면 해당 페이지가 포함된 블록 전체의 수명이 빠르게 소모된다.

이런 이유로 SSD는 수명을 위해서 모든 페이지가 균일하게 쓰기 작업을 해야 할 필요가 있다. 하지만 우리가 사용하는 FAT이나 NTFS와 같은 파일 시스템은 낸드 플래시 메모리 구조를 고려하고 있지 않다. 이런 문제를 SSD의 FTL 단계에서 해결하게 된다.

SSD는 페이지 레지스터를 통해서 모든 페이지마다 몇 번의 재기록이 이뤄졌는지를 관리하고 있다. 만약 어플리케이션 계층에서 재기록 작업이 들어오면, FTL은 각 페이지의 재기록 횟수를 참고해 주소 매핑 테이블에서 논리 주소와 물리 주소를 매핑해 주소를 반환하는 방법을 통해서 아직 덜 사용된 페이지를 위주로 재기록 작업을 진행한다.

즉, 웨어 레벨링은 주소 매핑 테이블의 내용을 수정해 논리 주소에 연결된 물리 주소 자체를 변경하는 것이라고 할 수 있다. 또한 기존의 페이지는 다른 논리 주소로 연결한다.

하지만 이 때 기존의 페이지에 있던 데이터는 그대로 둔다. 이 데이터를 삭제하기 위해서는 낸드 플래시 메모리의 특성상 블록 전체를 지운 뒤에 다른 페이지에 데이터를 다시 기록해야 하기 때문이다. 이 데이터는 쓰레기(garbage) 페이지라고 표시만 해 둔다.

이렇게 점차 필요 없는 데이터가 충분히 쌓이면 적절한 시점이 될 때 한번에 지우기 작업을 처리한다. 이 처리 과정을 GC(Garbage Collection)라고 한다.

웨어 레벨링
낸드 플래시 셀은 너무 빈번하게 쓰기-삭제 과정을 거치면 사용 불가능 사태가 되기 때문에, 셀 간의 작업을 분산해 각 블록들이 P/E 사이클 한계에 동시에 도달하도록 하는 것이 FTL의 중요한 목표 중 하나이다.

GC: Garbage Collection

SSD 컨트롤러의 GC 프로세스는 “Stale” 상태의 페이지들이 삭제되어 새로운 쓰기 데이터를 저장할 수 있도록 해 주는 과정이다.

플래시 메모리의 셀은 재기록 가능한 횟수가 정해져 있다. 쓰기 작업이 수행될 때마다 수명이 점점 줄어드는데, 통상적으로 SLC는 약 10만 회, MLC는 약 1만 회, TLC는 약 1천 회의 재기록이 가능하다고 알려져 있다.

때문에 SSD는 특정 셀에 집중된 쓰기 작업을 피하기 위해서 여러 셀이 골고루 사용될 수 있도록 데이터를 분산 저장하는 웨어 레벨링을 사용한다. 이와 더불어 셀의 수명을 늘리기 위해서 GC를 사용하고 있다.

셀의 수명을 위해서 플래시 메모리는 쓰기 작업을 최대한 골고루 이뤄지도록 해야 하며, 성능을 위해서 지우기 작업을 미뤄야 한다. 때문에 어떤 페이지에 재기록 요청이 오면 페이지의 내용을 지우고 쓰는 것이 아닌, 필요 없는 데이터가 담긴 페이지라고 표시만 한 후에 다른 비어있는 페이지에 데이터를 기록한다. 그리고 새로 기록한 페이지의 주소를 원래 페이지의 주소와 바꾸게 된다. 이런 과정으로 웨어 레벨링이 이뤄진다.

이런 과정을 반복하다보면 어느 시점이 되면 블록에 필요 없는 페이지들이 쌓이게 되는데, 충분히 지우기 작업을 진행해도 좋을 만큼 필요 없는 페이지들이 쌓이면 적절한 시점을 잡아서 유요한 페이지들을 한 곳을 모아 다른 블록으로 옮기고, 남은 블록들을 모아서 지우기 작업을 한다.

콜드 데이터와 핫 데이터
빈번하게 수정되는 데이터를 핫 데이터라고 하며, 자주 수정되지 않는 데이터를 콜드 데이터라고 한다. 만약 핫 데이터와 콜드 데이터가 동일한 페이지에 저장된다면, 핫 데이터가 변경될 때마다 콜드 데이터는 핫 데이터와 함께 Read-Modify-Write 오퍼레이션에 함께 포함되어 복사되어야 한다. 또한 웨어 레벨링을 위해서 콜드 데이터도 같이 계속 다른 페이지로 이동되어야 한다. 콜드 데이터와 핫 데이터는 최대한 분리해야 GC를 효율적으로 처리할 수 있다.

웨어 레벨링을 통해서 느린 지우기 작업을 최대한 미뤄서 성능을 올리고, 이렇게 모아진 쓰레기 페이지를 GC를 통해서 한번에 처리해서 효율을 극대화한다. 이 또한 작업 알고리즘의 중요성이 커서 제조사별로 성능의 차이가 있다.

GC 작업은 운영체제에서 관여하지 않으며, SSD가 자체적으로 수행한다.

OP: Over Provisioning

오버 프로비저닝

웨어 레벨링과 GC는 SSD의 핵심적인 기능이라고 할 수 있다. 또한 이 기능들의 목적은 가능한 모든 페이지가 고르게 사용될 수 있게 하고, 성능을 보장하며, 수명을 연장시키기 위한 것이다.

하지만 웨어 레벨링과 GC는 구조상 필연적으로 문제가 발생한다. 대부분의 셀이 사용된 상태에서는 특정 페이지들만 반복적으로 읽기/쓰기 작업을 해야 할 가능성이 커지게 된다. 또한 이를 피하기 위해서는 일반적인 상황보다 많은 작업들을 필요로 한다. 이런 문제는 SSD의 성능 감소와 수명 단축이라는 문제점을 가져온다.

때문에 SSD는 저장 공간이 전부 사용되고 있을 때에 대한 대비를 하기 위해서 오버 프로비저닝(OP: Over Provisioning) 공간이라는 것을 마련해 준다. 이와 같은 오버 프로비저닝 공간은 웨어 레벨링과 GC, 배드 블록 관리 등 SSD를 운영하는데 필요한 핵심적인 기능들의 성능을 유지하고 수명 연장에 도움을 준다.

내부 오버 프로비저닝 공간

내부 오버 프로비저닝 공간이란 출시될 때부터 SSD 자체에 내장되어 오직 오버 프로비저닝으로 사용될 목적의 공간이다. 즉, 제품 사양에 표기되는 용량 외에 숨어 있는 용량이 존재하고, 이 공간이 오버 프로비저닝 공간으로 활용되는 것이다. 이 공간은 SSD의 장치 단계에서 설정된 공간이기 때문에 사용자가 이 공간의 크기를 정확히 확인할 방법은 없다.

외부 오버 프로비저닝 공간

외부 오버 프로비저닝 공간은 내부 오버 프로비저닝 공간과는 다르게 일반적인 데이터 공간과 오버 프로비저닝 공간이 따로 분리되어 있지 않고, 광리 프로그램을 통해 수동으로 설정하거나 미리 설정된 조건에 맞으면 자동으로 오버 프로비저닝 공간을 할당하는 구조를 가지고 있다.

오버 프로비저닝은 웨어 레벨링과 성능 향상에 도움을 준다
SSD는 단순히 물리적인 공간보다 더 작은 크기로 논리적인 공간을 설정하면 오버 프로비저닝 공간을 만들 수 있다. 남은 공간은 사용자에게는 보이지 않지만, 컨트롤러는 여전히 그 공간을 사용할 수 있다.
오버 프로비저닝은 낸드 플래시 셀의 제한된 수명을 극복하기 위한 웨어 프로비저닝에도 도움이 된다. 쓰기 부하가 심하지 않을 때는 10~15% 정도의 오버 프로비저닝 공간으로 충분하다. 하지만 지속적인 랜덤 쓰기가 과도하게 발생할 때는 25% 정도의 오버 프로비저닝 공간이 성능을 향상시킨다.
오버 프로비저닝 공간은 낸드 플래시 블록의 버퍼처럼 동작하기 때문에, 쓰기가 포화되는 시첨에도 GC가 과도한 쓰기를 견딜 수 있게 해 준다.

낸드 플래시 메모리의 구조와 특성

셀의 데이터 저장 구조

N채널을 미리 구성해놓는 Depletion형을 기준으로 한다.

셀은 플로팅 게이트(FG)라는 곳에 전자를 채우고 비우는 방식으로 데이터를 기록하고 지운다. 플로팅 게이트는 절연체인 산화막으로 둘러 쌓여 있기 때문에 전자가 이동하지 못하고 닫힌 상태를 유지한다.

전자가 비어있는 상태에서 컨트롤 게이트(CG)에 충분한 전압을 걸어주면 발생하는 전기장의 영향으로 소스에서 드레인으로 이동하던 전자의 일부가 절연체인 산화막을 통과해 플로팅 게이트로 끌려 들어온다. 이런 현상은 **터널 효과**에 의한 것이며, 이렇게 플로팅 게이트에 전자를 채우는 것을 **터널 주입**이라고 한다.

그 후 컨트롤 게이트에 인가했던 전압을 끊으면 터널 효과가 사라지고, 결국 플로팅 게이트로 이동했던 전자들은 절연체인 산화막에 의해 플로팅 게이트 안에 갇히게 된다. 이런 과정을 통해서 셀의 쓰기 작업이 이뤄진다.

플로팅 게이트 안으로 들어간 전자는 절연체인 산화막에 의해 갇히게 되고, 갇힌 전자는 전기가 공급되지 않더라도 플로팅 게이트 안에 유지된다. 이런 특성으로 셀은 비휘발성 저장 매체로 사용된다. 플로팅 게이트에 갇힌 전자는 셀의 방식에 따라서 적게는 5년에서 길게는 10년까지도 유지된다.

반대로 P층에 충분히 큰 전압을 걸어주면 그 방향에서 발생한 전기장의 영향으로 플로팅 게이트에 갇혀 있던 전자들이 절연층인 산화막을 통과해 밖으로 빠져나가게 되고, 플로팅 게이트 안의 전자는 비워지게 된다. 이 과정을 **터널 릴리즈**라고 한다. 플래시 메모리 셀은 이 과정을 통해서 삭제 작업을 하고, 셀은 다시 쓰기 작업을 실행할 수 있는 상태가 된다.

읽기 작업은 컨트롤 게이트에 터널 효과가 발생하지 않을 정도의 약한 전압을 걸어주고, 소스에서 드레인으로 전압을 걸어 전하를 이동시키는 방법으로 이뤄진다.

컨트롤 게이트에 전압을 걸어주면 발생하는 전기장의 영향으로 P층의 정공(+)들이 밀려나고, 이는 N채널의 전도폭이 늘어나는 효과를 가져온다. 전기장의 세기가 더 크다면 더 많은 정공들이 밀려나고, 전기장의 세기가 약하다면 정공들이 덜 밀려난다. 즉, 컨트롤 게이트에서 발생한 전기장의 세기에 따라서 N채널의 전도폭이 결정된다.

하지만 플로팅 게이트에 채워진 전자가 전기장에 간섭을 일으키게 되는데, 더 많은 전자가 채워져 있을 수록 간섭도 그만큼 커진다. 그 결과로 N채널에 도달하는 전압이 변하게 되고, 컨트롤 게이트에 동일한 전압을 걸었을 때 플로팅 게이트에 채워진 전자의 양에 따라서 N채널의 전도폭이 달라진다.

읽기 작업이 수행될 때 플로팅 게이트에 채워진 전자의 양에 따라서 N채널의 전도폭이 변하게 되고, 이로 인해서 소스에서 드레인으로 이동하는 전하량(전류값)에 차이가 발생한다.

즉, 위와 같은 상황에서 소스로부터 드레인으로 이동하는 전류값을 분석하면 플로팅 게이트에 채워진 전자의 양을 파악할 수 있게 된다.

간단하게 SLC 방식을 기준으로 플로팅 게이트가 비워져 있으면 1, 채워져 있으면 0과 같은 방식으로 셀에 기록된 데이터가 무엇인지를 읽을 수 있다.

플로팅 게이트에 전자를 채워 넣으면 쓰기 작업
플로팅 게이트에 전자를 비우면 삭제 작업
플로팅 게이트에 채워진 전자(전하량)을 측정하면 읽기 작업

정리하자면 플래시 메모리의 셀은 터널 효과가 발생할 정도로 높은 전압을 인가해 플로팅 게이트에 전자를 채우고 비우는 방식으로 데이터를 기록하고 삭제한다.

그리고 기록된 데이터는 비트 라인을 통해서(source -> drain) 플로팅 게이트의 전하량을 측정하고 분석하는 방식으로 데이터를 읽는다.

노어 플래시 메모리와 낸드 플래시 메모리의 차이
플래시 메모리에는 셀을 연결한 논리 구조에 따라서 여러 종류가 있는데, 대표적으로 셀을 병렬 구조로 연결한 것이 노어 플래시 메모리이고, 셀을 직렬로 연결한 것이 낸드 플래시 메모리다. 노어 플래시 메모리와 낸드 플래시 메모리는 전체적인 구조에서도 많은 차이가 있지만, 가장 큰 차이는 셀을 병렬로 연결했는지 직렬로 연결했는지에 대한 차이다.

직렬 구조의 낸드 플래시 메모리

낸드 플래시 메모리는 이런 셀들을 직렬 구조로 연결시킨 것이다.

셀들은 블록(block)으로 그룹핑 되어 있으며, 블록들은 다시 플레인(plane)으로 그룹핑되어 있다. SSD의 읽기, 쓰기 작업에서의 최소 접근 단위를 페이지(page)라고 하며, 페이지는 개별로 삭제될 수 없고 반드시 삭제는 블록 단위로만 수행될 수 있다.

낸드 플래시 메모리의 페이지 크기는 2KB, 4KB, 8KB, 16KB 등으로 다양한데, SSD의 블록은 대부분 128개 또는 256개의 페이지를 가진다.

이는 SSD 제조사별로 블록의 크기가 256KB에서 4MB까지 다양하다는 것을 의미한다. 예를 들어서 삼성 SSD 840 EVO는 2048KB의 블록 크기를 가지며 각 블록은 256개의 8KB 페이지를 가진다.

읽기는 페이지 단위로 실행
한번에 하나의 페이지보다 작은 크기의 데이터를 읽을 수는 없다. 물론 사용자는 운영 체제에게 단 하나의 바이트만 읽기를 요청할 수는 있지만, 실제 SSD는 하나의 페이지를 통째로 읽은 다음 불 필요한 데이터는 모두 버리고 사용자가 요청한 한 바이트만 반환하는 것이다. 즉 불필요한 데이터를 많이 읽게 되는 것이다.

쓰기는 페이지 단위로 실행
쓰기를 실행할 때에도 SSD는 페이지 단위로, 하나의 페이지 또는 여러 개의 페이지로 실행된다. 그래서 단 하나의 바이트만 기록하는 경우에도 반드시 전체 페이지가 기록되어야 한다. 이렇게 필요 이상으로 쓰기가 발생하는 것을 Write Amplication이라고 하며, SSD의 페이지에 데이터를 쓰는 것을 프로그램(program)이라고 한다.

삭제는 블록 단위로 실행
페이지는 덮어쓰기가 불가능하기 때문에 한번 “stale” 상태로 된 페이지는 반드시 삭제하는 작업을 거쳐서 “free” 상태로 전이할 수 있다. 그러나 삭제는 단일 페이지 단위로 처리될 수 없고, 그 페이지가 포함된 블록을 통째로 삭제해야 한다. 사용자는 읽기와 쓰기 명령만 데이터 액세스를 위해서 사용할 수 있으며, 삭제 명령은 SSD 컨트롤러가 “free” 공간이 필요할 때 자동적으로 내부 명령을 실행해서 가비지 컬렉션을 실행할 때 사용된다.

WA: Write Amplification

쓰기는 페이지 사이즈에 맞춰서 실행되므로, 페이지 사이즈에 일치하지 않는 모든 쓰기는 필요 이상의 부가적인 쓰기(write amplication, 쓰기 증폭)를 필요로 한다. 한 바이트를 쓰기 위해서는 하나의 페이지를 통째로 써야 하므로, 페이지 사이즈가 16KB인 SSD에서는 16KB를 기록해야 하고, 이는 상당히 비효율적이다.

그러나 이것만 SSD의 문제점은 아니다. 필요 이상의 데이터를 쓰게 되면, 필요 이상의 내부 오퍼레이션을 유발한다. 페이지 크기에 맞춰지지 않은 쓰기는 먼저 해당 페이지의 데이터를 캐시로 읽어야 하며, 다시 페이지에 기록되어야 하기 때문에 즉시 페이지에 기록하는 것보다 느리게 동작한다. 이런 현상을 “read-modify-write”라고 하는데, 가능하다면 이런 현상은 피하는 것이 좋다.

웨어 레벨링

낸드 플래시 셀은 P/E 사이클이 제한되어 있고, 이는 제한된 수명을 가진다는 것을 의미한다. 예를 들어 하나의 블록에만 데이터를 읽고 쓰는 가상의 SSD가 있다고 해보자. 이 블록은 하주 빨리 P/E 사이클 제한을 넘어서게 되어 사용하지 못하게 될 것이다. 그러면 SSD 컨트롤러는 이 블록을 “사용 불가능”으로 마킹하게 된다. 결과적으로 SSD의 사용 가능한 공간이 줄어들게 된다.

이런 이유로 SSD 컨트롤러의 중요한 역할 중 하나는, SSD 전체 블록에 대해서 P/E 사이클이 골고루 분산되도록 쓰기(wear leveling)를 실행하는 것이다. 이상적으로는 모든 블록이 P/E 사이클 한계에 동시에 도달해 한번에 모든 블록이 사용 불가능 상태가 되는 것이다.

최고의 웨어 레벨링을 위해서는 쓰기가 발생하면 현명하게 블록을 선택해야 하며 때로는 특정 블록을 주위로 옮겨야 할 수도 있다. 이 과정에서 또 다른 WA가 발생하는 것이다. 그래서 블록 관리는 WA와 웨어 레벨링 사이에서 적절히 타협점을 찾아야 하는 것이다. 그래서 SSD 제조사들은 가비지 컬렉션과 같은 웨어 레벨링을 위한 기능들을 가진 제품들을 출시하고 있다.

수명 제한
각 셀은 최대 P/E 사이클을 가지는데, 이 사이클을 넘어서면 결함 셀로 간주된다.
낸드 플래시 메모리는 수명 제한을 가지는데, 이 수명 제한은 낸드 플래시 메모리의 종류에 따라서 조금씩 차이가 있다.

셀의 종류

SLC: Single Level Cell

  • 트랜지스터에 1비트만 저장할 수 있지만 상대적으로 긴 수명을 가짐
  • 재기록 가능 횟수(P/E cycle): 100k

MLC: Multiple Level Cell

  • 트랜지스터에 2비트를 저장할 수 있으며, SLC에 비해서 상대적으로 레이턴시가 높고 짧은 수명을 가짐
  • 재기록 가능 횟수(P/E cycle): 10k

TLC: Triple-Level Cell

  • 트랜지스터에 3비트를 저장할 수 있지만, MLC보다 레이턴시가 높고 수명이 더 짧음
  • 재기록 가능 횟수(P/E cycle): 5k

플래시 메모리의 셀은 일정한 횟수만 재기록이 가능하며, 이후부터는 재기록이 불가능해지는 특성이 있다. 즉, 재기록 가능 횟수가 만 번이라면 해당 플래시 메모리 셀은 만 번의 재기록(Erase, Write)이 가능하며, 이후부터는 더이상 재기록이 불가능하다.

셀의 운용(데이터 저장) 방식

SLC나 MLC, TLC 모두 셀은 동일하다. 하지만 셀에 데이터를 저장할 때 컨트롤 게이트에 인가한 전압에 따라서 플로팅 게이트로 주입되는 전자의 양이 달라진다. 그리고 플로팅 게이트에 채워진 전자의 양을 파악하는 것도 가능하다. SLC는 단순히 플로팅 게이트에 전자를 채우고 비운다는 개념만을 가지고 셀을 운용했다면, MLC와 TLC는 플로팅 게이트에 전자를 얼만큼 채우면 그건 이런 데이터라는 개념으로 셀을 운용한다.

셀의 운용 방식에 따라 발생하는 차이의 이해

셀의 데이터 저장 방식은 “전자를 채우는 방식”이라고 말할 수 있다. 그런데 문제는 이 전자가 채워지는 양이 정확하게 딱 맞아 떨어지지 않는다는 것이다. 즉, 컨트롤 게이트에 10V의 전압을 가하면 플로팅 게이트에 정확하게 100개의 전자가 채워지지 않는다.
때문에 실질적으로 컨트롤 게이트에 특정 전압을 걸어주면 플로팅 게이트에 일정 범위를 두고 전자가 채워진다. 셀의 데이터를 읽는 것 역시 플로팅 게이트의 전하량이 “일정 범위 안에 있으면 어떤 데이터로 읽자”와 같은 방식으로 데이터를 읽는다.

셀에 데이터를 기록하는 것을 매우 단순하게 정의하면, 해당 데이터에 맞게 설정된 전압을 인가해주는 방식으로 정의할 수 있다. 이 정의를 토대로 터널 효과가 발생하는 최소 전압을 1V, 컨트롤 게이트에 인가할 수 있는 한계 전압을 16V로 놓고 그림을 그려보면 SLC와 MLC, TLC의 데이터 저장 구조는 아래와 같다.

먼저 하나의 그래프를 플로팅 게이트의 공간으로 생각해보자. 그럼 SLC는 각 데이터를 규정하는 범위간의 간격이 넓고, TLC는 이 간격이 좁은 것을 알 수 있다. TLC는 각 영역 간의 간섭이 일어나지 않을 정도로 촘촘하게 셀을 운용하고 있다고 보면 된다.

이런 차이로 인해서 SLC는 데이터를 저장하고 읽는 데에 오류가 적지만, MLC나 TLC는 데이터를 저장하고 읽는데 그 간격이 상대적으로 좁기 때문에 오류가 많이 발생하게 된다. 특히 거의 한계까지 간격을 좁힌 TLC는 생각보다 빈번한 오류가 발생하게 된다.

때문에 낸드 플래시 메모리는 데이터 오류를 검출하고 수정할 수 있도록 데이터와 함께 ECC 오류 검출 정보를 함께 저장한다. 오류 검출 정보를 통해서 일정한 비트까지의 오류는 스스로 정정할 수 있고, 일정한 비트 이상의 오류는 검출만 가능하다.

SLC는 오류 발생 빈도가 낮기 때문에 ECC 코드가 가볍게 구성되어 있는 반면, MLC나 TLC로 갈 수록 오류 발생 빈도가 높아지기 때문에 기만큼 더 강력하고 복잡한 방식의 ECC 코드가 사용된다.

ECC 코드가 복잡하다는 말은 그만큼 저장해야 할 ECC 코드의 양이 늘어나고, ECC 코드를 해석하기 위한 시간도 오래 걸린다는 의미다. 때문에 전체적인 데이터의 읽기, 쓰기, 지우기 시간이 상대적으로 느려지게 된다. 이런 이유가 SLC와 MLC, TLC의 성능 차이의 주된 원인이라고 할 수 있다.

셀 쓰기와 지우기시 발생하는 터널 효과

셀에 데이터를 저장하고 지우면 전자가 절연체인 산화말을 통과하는 터널 효과가 발생한다. 하지만 전자들이 산화막을 뛰어 넘는 과정에서 일부 전자들이 산화막에 축적되는 현상이 발생한다. 즉, 전자가 산화막을 통과하다가 붙들려 산화막에 남아있게 된다.

이런 현상이 문제로 여겨지는 이유는, 산화막에 전자들이 축적되면 산화막의 저항값이 변하게 된다. 산화막의 저항값이 변한다는 것은 동일한 터널 효과(동일한 양의 전자 이동 효과)를 발생시키기 위해서 초기보다 더 높은 전압이 필요하다는 뜻이다. 즉, 셀에 쓰기와 지우기가 반복될수록 셀을 쓰고 지우기 위해서 점점 더 높은 전압을 인가해주어야 한다. 플래시 메모리는 이 문제를 해결하기 위해서 데이터를 기록하고, 삭제하는데 인가하는 전압의 크기를 점차 조정하는 방식을 사용한다.

하지만 작업에 인가해줄 수 있는 전압에는 한계가 있다. 쓰기 및 지우기가기 P/E 사이클에 도달하면 너무 커진 산화막의 저항값으로 인해서 더이상 터널 효과를 발생시킬 수 없게 된다. 즉, 셀에 더이상 쓰기 및 지우기를 할 수 없게 되는 것이다.

이 때 SLC는 각 상태별 전압의 차이가 크고 여유 전압도 보다 넓게 구성할 수 있기 때문에 절연층인 산화막의 저항이 변하는데 유연하다. 하지만 MLC나 TLC의 경우는 각 상태별 전압의 폭이 좁고 여유 전압도 얼마 되지 않기 때문에 전압 조절을 통한 대응 방식이 근방 한계에 도달하게 된다. 이것이 바로 SLC에서 MLC, TLC로 갈수록 수명이 급격하게 줄어드는 원인이다.

추가로 갈수록 플래시 메모리 제조 공정이 미세화되고 있는데, 공정이 미세화된다는 것은 각 셀을 이루는 구성 요소도 그만큼 작아졌다는 것을 의미한다. 때문에 똑같은 크기의 다이에 상대적으로 많은 용량을 가진 플래시 메모리의 제조가 가능해졌다. 이는 제조 원가의 절감으로 이어지게 된다.

하지만 이로 인해서 절연층인 산화막의 크기도 그만큼 작고 얇아졌으며, 재기록시 산화막의 저항이 그만큼 더 빨리 변하게 된다. 때문에 플래시 메모리는 제조 공정이 미세화될수록 용량은 늘어나지만 수명은 줄어들게 된다.

TRIM

간단하게 표현하면 **파일을 지우면 SSD에서도 실제로 파일을 지우는 기능**이라고 할 수 있다.

운영체제의 파일 삭제 구조

운영체제에서 파일을 삭제하더라도 실제로 디스크에서는 파일이 삭제되지 않는다. 운영체제에서 이런 방식을 취하는 이유는 디스크에서 파일을 실제로 삭제하게 되면 파일을 기록하는 것만큼 실제 작업도 오래 걸리게 되기 때문이다. 즉, 성능상 좋지 않기 때문이다.

HDD는 특성상 디스크에서 실제로 데이터를 지울 필요가 없다. 덮어쓰기(overwrite)로 이전의 데이터를 지울 필요 없이 데이터 위에 다른 데이터를 쓰는 것이 가능하기 때문이다. 즉, HDD는 데이터를 쓰기 위해서 섹터가 비어있던지 비어있지 않던지 상관이 없다.

때문에 운영체제는 파일을 삭제하면 파일의 메타데이터만 삭제해 파일 시스템과 실제 파일과의 연결만 끊고 굳이 디스크에서 데이터를 실제로 삭제하지는 않는다. 디스크를 사용하다보면 다른 파일들에 의해서 덮어쓰기가 이뤄져 기존의 파일들은 자연스럽게 사라지기 때문이다. 운영체제의 기본적인 파일 삭제 구조는 이런 HDD의 동작 방식을 염두했다.

플래시 메모리를 사용한 SSD의 등장

하지만 HDD와는 전혀 다른 동작 방식을 가진 SSD가 등장한다. SSD는 플래시 메모리를 효율적으로 구성해서 성능을 끌어올렸지만 지금까지 운영체제에서 파일을 삭제하던 방식이 SSD에서 문제가 되기 시작했다.

SSD는 플래시 메모리를 기반으로 하는 저장 매체다. 그 중에서도 낸드 방식의 메모리를 주로 사용한다. 이 플래시 메모리는 기계적인 구동 장치 없이 오직 전기적인 신호로만 데이터를 읽고 쓰기 때문에 기계적인 구동부를 가진 HDD보다 접근속도에서 큰 이점을 가지고 있다. 또한 읽기와 쓰기 속도도 빠른 편이라고 할 수 있다. 특히 접근 속도는 HDD와 비교를 할 수 없을만큼 빠르다고 할 수 있다. SSD는 플래시 메모리를 여러개의 채널로 연결해 성능을 지금의 수준까지 끌어 올렸다.

낸드 플래시 메모리의 저장 구조와 특성

낸드 플래시 메모리는 페이지와 블록의 구조로 이뤄져 있다. 블록 안에 페이지들이 모여 있고, 플래시 메모리 칩 안에 블록들이 모여 있는 구조다. 이런 낸드 플래시 메모리의 구조를 추상적으로 표현하면 아래와 같다.

낸드 플래시 메모리는 종류에 따라 다르지만 일반적으로 페이지는 4KB, 블록은 512KB의 크기로 이뤄져 있다. 즉, 일반적으로 읽기와 쓰기 작업은 4KB의 단위로 이뤄지고, 지우기 작업은 512KB의 단위로 이뤄진다. 이전에 언급했던 것과 같이 낸드 플래시 메모리는 기존의 데이터가 남아있을 때 페이지에 기록을 하는 것이 불가능하다. HDD에서는 간단하게 덮어쓰기로 가능했던 작업을, 플래시 메모리에서는 반드시 지우기 후에 쓰기 순서로 작업을 해야 한다. 특정한 페이지를 재기록하기 위해서는 512KB 크기에 해당하는 블록 전체를 먼저 지워야 한다는 치명적인 단점이 생긴다.

플래시 메모리의 쓰기/지우기 특성의 문제점

이런 구조적인 문제가 있기 떄문에 플래시 메모리는 비어있지 않은 페이지에 데이터를 기록하기 위해서는 블록의 나머지 데이터들을 같이 지워야만 하는 문제점이 발생한다. 때문에 SSD에서는 먼저 블록의 전체 데이터를 SSD 내부의 캐시로 옮긴 후 블록을 비우고 캐쉬에서 기존의 데이터와 새로운 데이터를 결합한다. 그리고는 최종적으로 캐쉬에서 결합한 데이터를 다시 블록 전체에 기록한다.

즉, 플래시 메모리를 사용하는 SSD에서는 4KB의 데이터를 기록하더라도 페이지가 비어있지 않다면 512KB에 달하는 블록 전체의 데이터를 옮긴 후에 비우고 결합해 다시 쓰는 작업을 진행해야 하는 문제가 있다. 이 문제는 SSD 뿐만 아니라 플래시 메모리를 사용하는 모든 저장 매체에서 공통적으로 발생하는 문제이다.

TRIM 명령의 등장

운영체제는 기본적으로 파일을 삭제하면 디스크에서 파일을 실제로 지우는 것이 아니라, 파일의 메타데이터를 삭제해 파일 시스템과의 연결을 끊고 디스크에 파일을 그대로 남겨 놓는다. 즉, 디스크는 사용할수록 실제로 사용되지 않는 쓰레기 데이터가 점점 늘어나 그만큼 공간을 차지하고 있게 된다.

이런 것들이 HDD를 사용할 때는 크게 문제가 되지 않았는데, 플래시 메모리를 사용하는 SSD를 사용하게 되면서부터 쓰레기 데이터들이 SSD의 전체 데이터 쓰기성능에 큰 영향을 미치게 된다. 데이터가 기록된 페이지가 많다는 것은 쓰기 작업에서 이 데이터들을 만날 가능성이 높아진다는 것이고, SSD는 기록을 하기 전에 지우기 작업을 먼저 실행해야 할 확률이 높아진다는 것을 의미한다.

SSD를 구매한 직후에는 모든 페이지와 블록이 비워져 있기 때문에 빠른 쓰기 속도를 유지할 수 있지만, 사용할수록 점점 재기록의 필요성이 늘어나면서 SSD의 전체적인 쓰기 성능이 큰 폭으로 하락하는 문제가 발생하게 된다. 이는 SSD의 쓰기 성능이 얼마나 많은 페이지와 블록이 쓰레기 데이터 없이 비워져 있느냐에 달려 있다고 볼 수 있다.

이 문제를 해결하기 위해서 SSD에서는 TRIM 명령이 새롭게 등장하게 된다. TRIM 명령은 운영체제에서 삭제된 쓰레기 파일들을 파악해 SSD상에서도 실제로 해당 파일들을 지우는 기능이라고 할 수 있다. 쉽게 생각하면, 기록할 때에만 지우기 작업을 하는 것이 아니라, 기록하기 전에 미리 지우기 작업을 해 놓는 것으로 생각하면 된다. 정말 단순하게 생각하면 운영체제에서 파일을 지우면, SSD에서도 실제로 파일을 지우는 것이라고 생각하면 된다.

TRIM 명령의 동작 방식

TRIM의 동작 방식에는 크게 두 가지를 생각할 수 있다.

1. 운영체제에서 파일을 삭제했다고 알려주면 SSD에서도 즉시 파일 삭제
2. 운영체제에서 파일을 삭제했다고 알려주면 SSD에서 자체적으로 표시해 두었다가 적절한 순간에 삭제

1번의 경우 간단하고 확실하지만, 파일을 삭제할 때마다 그만큼 딜레이가 발생하고, 프리징 현상이 발생할 수 있다는 단점이 있다.

2번의 경우 파일이 삭제된 파일이라고 할려주면 페이지에 표시를 하고, 나중에 SSD가 유휴 상태일 때 적절한 타이밍에 삭제하기 때문에 딜레이가 발생하지 않는다는 장점이 있다. 하지만 페이지를 표시하고, 삭제를 위한 최적의 타이밍을 잡기 위한 알고리즘의 설계가 복잡해지는 문제가 있다. 그래서 2번과 같은 방식의 경우 이 알고리즘을 얼마나 잘 구성하느냐에 따라서 SSD의 전체적인 성능이 결정된다고 할 수 있다.

최근의 SSD 컨트롤러들은 1번보다는 2번의 방식을 주로 사용하며, SATA 3.1 규격에서는 Queued Trim Command를 추가해 SATA 규격 자체에서 TRIM 명령을 최적화하기 위해서 준비하고 있다.

내부 병렬 처리

제한된 I/O 버스 대역폭

물리적인 한계로 인해서 비동기 방식의 낸드 플래시 I/O 버스는 32~40MB/s 대역폭 이상을 서비스할 수 없다. 제조사의 입장에서 SSD의 성능을 향상시킬 수 있는 유일한 방법은 다수의 패키지가 병렬로 처리되거나, 인터리빙(interleave) 모드로 동작하도록 설계를 변경하는 것이다.

SSD 아키텍처에서 여러 레벨의 내부적인 병렬 처리 능력을 묶어서 동시에 2개 이상의 블록을 액세스할 수 있다. 이렇게 동시에 접근 가능한 블록을 묶어서 클러스터드 블록(Clustered Block)이라고 한다.

내부 병렬 처리(Internal parallelism)
내부적으로 여러 레벨의 병렬 처리 능력이 서로 다른 낸드 플래시 칩에서 2개 이상의 블록을 동시에 읽을 수 있도록 해주는데, 이를 클러스터드 블록이라고 한다.

병렬 처리

1. Channel-level Parallelism

플래시 컨트롤러는 여러 채널을 통해서 플래시 패키지와 통신한다. 이 채널들은 서로 독립적이며 동시에 액세스 가능하다. 각 채널은 여러 패키지에 의해서 공유된다.

2. Package-level Parallelism

채널의 패키지들은 독립적으로 접근이 가능하다. 동일한 채널을 공유하는 패키지들은 인터리빙 모드로 동시에 명령을 실행할 수 있다.

3. Chip-level Parallelism

패키지는 하나 또는 두개의 칩(또는 다이)을 가지며, 각 칩들은 독립적으로 병렬 접근이 가능하다.

4. Plane-level Parallelism

각 칩은 2개 이상의 플래인을 가지는데, 동일한 오퍼레이션은 하나의 칩 내의 여러 플레인에 대해서 동시에 실행이 될 수 있다. 플레인은 블록을 가지며, 각 블록은 다시 페이지를 가진다. 또한 플레인은 플레인 단위의 오퍼레이션에 사용되는 레지스터를 가진다.

클러스터드 블록

여러 칩에 걸처서 한번에 액세스될 수 있는 블록들을 말한다. RAID 시스템에서 사용되는 스트라이핑(striping)과 비슷한 아이디어다.

한번에 접근 가능한 논리 블록 주소들은 각각의 플래시 패키지에서 서로 다른 SSD 칩들에 걸처서 스트라이핑된다. 이는 FTL의 매핑 알고리즘을 사용하며, 클러스터드 블록 내부의 블록들이 서로 연속된 주소일때도 문제 없이 독립적이다.

클러스터드 블록들은 여러 채널을 동시에 사용할 수 있으며, 그 채널들의 대역폭을 묶어서 사용할 수 있다. 또한 읽기와 쓰기, 삭제 오퍼레이션을 병렬로 처리할 수 있다. 이는 클러스터드 블록의 사이즈 또는 그 배수 크기의 I/O 오퍼레이션은 SSD의 내부 병렬 처리 능력을 최대한 활용할 수 있다는 것을 보장한다.

NCQ: Native Command Queueing

NCQ는 SSD가 내부적인 병렬 처리 능력을 이용해서 동시에 여러 호스트 명령을 처리할 수 있도록 해주는 SATA의 기능이다.

SSD는 호스트와의 레이턴시 차이를 극복하기 위해서 NCQ를 사용한다. 예를 들어 호스트 CPU가 바쁠 떄는 드라이버가 항상 명령을 처리할 수 있도록 유입되는 명령의 우선순위를 높여줄 수 있다.

빠른 응답 속도를 위해서 새로운 드라이버는 NCQ를 사용하는데, NCQ는 호스트의 명령을 큐잉해 우선순위를 재설정하고 때로는 지연처리를 하기도 한다.

--

--