페이징
페이징은 연속된 물리 메모리 공간 없이도 프로세스가 실행될 수 있도록 하는 메모리 관리 기법이다.
물리 메모리는 프레임이라는 고정 크기 블록으로, 논리 메모리는 페이지라는 동일 크기 블록으로 나눠지고, 이 둘은 일대일로 매핑된다.
프로그램이 메모리에 올라갈 때 페이지 테이블을 통해 논리 주소의 페이지 번호를 물리 주소의 프레임 번호로 바꾸고, 거기에 페이지 오프셋을 더해 실제 주소를 계산한다.
이 작업을 MMU가 자동으로 해주고, 덕분에 물리 주소가 연속되지 않아도 된다. 그래서 외부 단편화가 원천적으로 사라진다.
하지만 페이지 단위로만 할당하기 때문에 프로세스 크기와 페이지 크기가 안 맞으면 마지막 페이지에서 내부 단편화가 생긴다.
예를 들어 2048B짜리 페이지를 썼는데, 마지막 페이지에 1000B만 차는 식이다.
페이지 크기가 작을수록 단편화는 줄지만, 페이지 테이블이 길어지고 관리 비용이 커진다.
CPU는 논리 주소를 기준으로 계산하고, 실제 메모리 위치는 운영체제가 프레임 테이블로 추적한다.
페이지 테이블은 프로세스마다 별도로 있고, 거기서 각 논리 페이지가 어떤 물리 프레임에 매핑돼 있는지 기록한다.
그래서 프로세스가 접근할 수 있는 주소는 자기 페이지 테이블로만 제한되고, 다른 프로세스 주소는 구조적으로 접근할 수 없다.
이게 곧 메모리 보호 기능까지 포함하는 구조가 되는거다.
또, 페이지 프레임들은 시스템 전체에서 공유되는 자원이기 때문에, 운영체제는 프레임이 할당됐는지 비어있는지 여부를 프레임 테이블로 관리한다.
그리고 새로운 프로세스를 시작할 때는 이 프레임 테이블을 기준으로 사용 가능한 프레임들을 찾아, 그 안에 페이지를 할당하고 페이지 테이블에 기록해준다.
이 덕분에 메모리가 여러 조각으로 흩어져 있어도 문제 없이 프로세스 실행이 가능하고, 운영체제 입장에서도 유연하게 메모리를 배분할 수 있게 된다.
TLB
페이징 시스템에서 논리 주소를 물리 주소로 바꾸려면 페이지 테이블을 참조해야 하는데, 이게 메모리에 있기 때문에 매번 참조하면 느리다.
그래서 CPU는 페이지 테이블을 빨리 접근할 수 있게 하기 위해 TLB라는 캐시를 둔다.
이건 말 그대로 "최근 자주 쓰는 페이지 매핑 정보를 따로 저장해두는 캐시" 이고, 여기서 매핑 정보를 찾으면 빠르게 주소 변환이 가능하다.
페이지 번호 -> 프레임 번호 매핑을 기억하고 있는 건데, 이걸 통해 실제 메모리 접근보다 훨씬 빠른 속도로 주소 변환이 가능해진다.
만약 TLB에 매핑 정보가 없다면, 그 때 페이지 테이블을 참조하고, 거기서 가져온 정보를 TLB에 다시 저장한다. 이걸 TLB 미스라고 하고, 그만큼 성능 저하가 생긴다.
그래서 시스템은 TLB hit ratio를 높이는 게 중요하다. 이 비율에 따라 메모리 접근 지연시간이 수십 나노초까지 차이날 수 있다. 게다가 CPU는 Context switch시에도 이전 프로세스의 페이지 테이블과 TLB정보를 날려버리면 성능이 떨어지니까, ASID라는 ID를 붙여서 프로세스마다 TLB를 구분하고, Context switch이 일어나도 TLB 정보를 유지할 수 있게 한다.
요즘 CPU들은 L1, L2 캐시에 TLB까지 여러 계층으로 갖고 있고, 이 구조 덕분에 TLB miss를 최소화 할 수 있다.
하지만 TLB는 하드웨어 장치기 때문에, OS가 이를 활용하려면 CPU에 맞는 구조로 설계를 해야 한다.
Redis는 인메모리에서 모든 데이터를 처리하는 시스템이기 때문에, 그 어떤 DB보다 메모리 접근 효율이 중요하다.
그리고 Redis가 어떤 Key를 조회할 때, 결국 내부적으로 malloc으로 확보한 메모리 주소에 접근하게 된다.
이 주소는 논리 주소고, CPU는 이를 물리 주소로 바꿔야 한다.
이때 TLB에 매핑 정보가 있으면 바로 변환돼서 빠르고, 없으면 페이지 테이블을 참조해야 해서 느려진다.
즉, Redis에서 Hot Key가 자주 접근되면, 그 데이터는 같은 페이지 안에 있을 확률이 높고, 페이지 번호도 반복되니까 TLB hit가 잘 일어난다. 이게 Redis 성능이 잘 나오는 이유 중 하나다.
반대로, 데이터가 여기저기 흩어져 있고 수많은 Key가 한번씩만 조회되면 TLB miss가 많이 나고 성능 저하가 생긴다.
특히 큰 hash, list, stream같은 자료구조를 random access할 경우 TLB miss가 급격히 늘어날 수 있다.
'독서기록장' 카테고리의 다른 글
8. 운영체제 9장 메모리 (3) 연속 메모리 할당 (0) | 2025.03.30 |
---|---|
7. 운영체제 9장 메모리 (2) with java spring.. (0) | 2025.03.29 |
6. 운영체제 9장 메모리 (1) with redis.. (0) | 2025.03.28 |