상세 컨텐츠

본문 제목

SSD story (1) : GC (Garbage Collection) Implementation.

운영체제

by 허브포트 2023. 7. 24. 13:28

본문

이번 포스팅에서는 SSD 최적화를 설명하기에 앞서 SSD에서 꼭 필요하지만 overhead가 큰 GC를 구현하는 기본적인 틀에 대해서 이야기하고자 한다.

 

1. SSD Aging

SSD Aging은 SSD에 정보가 저장됨에 따라 시간이 지날수록 성능이 감소하는 현상이다.

출처 : The Multi-streamed Solid-State Drive : https://www.usenix.org/system/files/conference/hotstorage14/hotstorage14-paper-kang.pdf

 Normal(TRIM off) 부분을 주목해보라. 시간이 지날수록 성능이 감소하는 것을 볼 수 있다.

 

이런 SSD Aging은 Garbage Collection과 연관이 있다.  Garbage Collection은 무엇인데 SSD의 성능을 저하시킴에도 불구하고 사용되는 것일까?

(하단의 링크를 참조해주세요~)

https://www.kingston.com/kr/blog/pc-performance/ssd-garbage-collection-trim-explained

 

SSD 성능을 위한 가비지 컬렉션과 TRIM 프로세스의 중요성

SSD 기술의 세계에서 가비지 컬렉션과 TRIM이라는 용어가 종종 보이곤 합니다. 하지만 이 용어들이 정말로 의미하는 바는 무엇일까요? 이 기사에서는 가비지 컬렉션과 그 작동 방식, TRIM 명령어와

www.kingston.com

 

2. GC (Garbge Collection)

Garbage Collection은 말그대로 쓰레기를 정리하는것이다. 

SSD에서 쓰레기란 Invalid Page를 뜻한다.

 

Invalid Page는 무엇일까? 

 

예를들어 내가 C라는 내용을 사전에 SSD에 썼다고 가정해보자. 그 이후 나는 컴퓨터에서 C라는 내용을 C'으로 수정하였다. 그러면 SSD에 이전에 기록된 C를 사용하지 않는다고(Invalid) 처리하고, SSD에 C'이란 내용을 새로 써준다.

이 과정에서 발생하는 C를 Invalid Page라고 한다. 

 

이 쓰레기들을 한번 정리해보자.

 

Log-Structure File system 기반의 기본적인 PFTL의 GC는 다음과 같이 수행된다.

SSD GC 과정

0. Victim이 될 Block을 하나 선정한다. ( 보통 Invalid Page가 가장 많은 Block을 고른다 )

1. Block 내부를 순회하면서 Invalid Page를 무시하고 Valid Page만 DRAM에 올린다.

2. DRAM에 올라간 Valid Page를 Open Block에 넣어서 SSD에 다시쓴다.

3. Victim이된 Block에 ERASE 연산을 적용한다.   

 

하단의 코드는 필자가 구현한 GC 코드이다. 실제 SSD에서 돌아가는 것은 아니고, Page FTL을 시물레이션 돌려보기 위해 작성한 코드이다.

 

상세한 코드는 Github을 참고바랍니다.

int GC (ssd_t* my_ssd, _queue* free_q) {
        if (my_ssd->flag_GC == GC_T) {
                return -1;
        }

        if (free_q->size > THRESHOLD_FREE_Q) {
                return -1;
        }
        
	// GC flag setting
        my_ssd->flag_GC = GC_T;

	// Victim Selection
        int block_n_victim = get_victim(my_ssd);
        block_t* block_victim = my_ssd->block[block_n_victim];
	
    	// Block을 순회하면서 Valid Page를 SSD에 써준다.
        int i;
        for(i = 0; i < PAGE_NUM; i++) {

                int page_bit = block_victim->page_bitmap[i];
                if (page_bit == INVALID) {
                        continue;
                }

                // a page_bit is valid
                int PPN = free_q_pop(my_ssd, free_q);
                int LBA = block_victim->LBA[i];
                ssd_t_write(my_ssd, PPN, VALID, LBA);
        }
	
 		// Page를 지워준다.
        page_erase(my_ssd->block[block_n_victim]->page_bitmap);
        
        my_ssd->block[block_n_victim]->invalid_page_num = 0;
		
        // Block을 Free Queue에 넣어줘서 다음에 사용할 수 있도록 해준다.
        q_push(free_q, my_ssd->block[block_n_victim]);


        my_ssd->flag_GC = GC_F;
}

 

https://github.com/pragma5501/PFTL

 

GitHub - pragma5501/PFTL

Contribute to pragma5501/PFTL development by creating an account on GitHub.

github.com

 

댓글 영역