이 글은 책 컴퓨터 밑바닥의 비밀 chapter 5.1의 내용을 읽고 요약한 글입니다.
5.1.1 CPU와 메모리의 속도 차이
- CPU 속도는 1년에 52%씩 성능이 증가한 반면, 메모리 속도는 1년에 7%씩 증가
- CPU는 명령어를 실행할 때 어쩔 수 없이 메모리의 처리를 기다려야 함
- 일반적인 시스템에서 메모리의 속도는 CPU의 100분의 1
5.1.2 도서관, 책상, 캐시
- 도서관에서 책상은 캐시에 비유할 수 있고, 서가는 메모리에 비유 가능
- CPU와 메모리 사이에 캐시 계층이 추가되어, 최근에 메모리에서 얻는 데이터가 저장됨
- 캐시가 적중하면 메모리에 접근할 필요가 없어 CPU가 명령어 실행하는 속도를 크게 끌어올릴 수 있음
- 캐시 적중: CPU가 요청한 데이터가 캐시에 이미 저장되어있어 캐시가 해당 요청을 이행할 수 있을 때 발생
- 일반적으로 x86 CPU와 메모리 사이에는 세 단계의 캐시가 추가 되어 있음
- L1, L2, L3
- L1 캐시 접근 속도: 레지스터 접근 속도에 비해 약간 느리지만 대동 소이하기 때문에 대략 4클럭 주기가 소요됨
- L2캐시 접근 속도: 대략 10클럭 주기 소요
- L3캐시 접근 속도 : 대략 50클럭 주기 소요
- 캐시 단계에 따라 접근 속도는 낮아지지만 용량을 증가
- L1, L2, L3 캐시, CPU 코어는 레지스터 칩 내에 묶여 패키징되어 있음
- CPU가 메모리 내에 데이터가 필요하다고 판단하면 우선 L1 캐시에서 데이터를 검색
- 없다면 L2, L3 를 순차적으로 검색 후 모두 없으면 메모리에 직접 접근하여 캐시에 데이터를 갱신
5.1.3 공짜 점심은 없다: 캐시 갱신
불일치 문제
- 캐시의 데이터는 갱신되었지만 메모리의 데이터는 아직 예전 것이 남아 있어 캐시와 메모리 사이에 불일치가 발생할 수 있음
해결 방법
1. 연속 기입(write-through)
- 캐시를 갱신할 때 메모리도 함께 갱신하는 방법
- 캐시를 업데이트하면 어쩔 수 없이 메모리에 접근해야 함 → CPU는 메모리가 갱신될 때까지 대기하고 있어야 함 → 동기식 설계 방법
- 이 상황을 최적화하는 방법은 동기를 비동기로 바꾸는 것
2. 후기입(write-back)
- 캐시 용량에 한계가 있어 용량이 부족하면 자주 사용되지 않는 데이터를 제거해야 함
- 캐시에서 제거된 데이터가 수정된 적이 있다면 이를 메모리에 갱신해야 함
- 캐시의 갱신과 메모리의 갱신이 분리되므로 비동기임
- 연속 기입보다 훨씬 복잡하지만 성능은 분명 더 나음
자주 사용할만한 데이터를 캐싱하는데, 삭제할 때만 메모리에 갱신하는 방식이 후기입
5.1.4 세상에 공짜 저녁은 없다: 다중 코어 캐시의 일관성
- 단일 CPU 성능 향상이 어려워 숫자를 늘리게 됨 → 다중 코어 시대 진입
- CPU가 코어를 여러개 가지면 다른 문제가 발생하는데 두 코어에서는 다른 스레드 2개가 실행됨
Step 1
- 두 스레드 모두 메모리 내 X변수에 접근해야하고 변수의 초기값이 2라고 가정
- 코어 2개는 모두 X 변수를 사용해야 한다
캐시 동작 원리에 따르면,
- 처음으로 X 변수를 읽으면 캐시에 적중할 수 없으므로 X 변수를 메모리에서 읽어야 함
- 이어서 대응하는 캐시에 갱신되므로, 이제 cpu1 캐시와 cpu2 캐시는 모두 X 변수를 가지고 있고 그 값은 2
Step2
- C1은 X 변수에 2를 더해야 하는데 캐시 동작 원리에 따라 C1은 캐시에서 X 변수 값을 가져온 후 2를 더해서 다시 캐시에 갱신
- 이 시스템이 연속 기입(write-through) 방식이라고 가정하면 메모리도 동기 방식으로 동시에 갱신되고 메모리에 있는 X 변수 값은 4
Step3
- cpu2 도 X 변수에 덧세 연산을 수행하는데 4를 더한다고 가정
- 캐시 동작 원리에 따라 cpu2는 캐시에서 X 변수 값을 가져온 후 4를 더해서 다시 캐시를 갱신
- 캐시 값은 6으로 바뀌는데 연속 기입 방식에 따라 메모리를 갱신하면 메모리에 저장된 값도 6이 됨 ⇒ 문제 바생
- 초기 값이 2인 변수에 2 와 4를 각각 더한 후 결과는 8이 되어야 하지만 X 변수 값은 6이 됨
문제는 메모리의 X 변수에 cpu1, cpu2의 캐시에 복사본 2개를 가지고 있기 때무네 발생하고 C1 캐시가 갱신될 때 C2 캐시는 동기적으로 수정되지 않아 다중 코어에서 캐시 데이터의 불일치 문제가 발생함
⇒ 해결책: 캐시 한개에 갱신된 변수가 다른 CPU 코어의 캐시에도 존재한다면 함께 갱신되어야 함
- 최신 CPU에는 고전적인 MESI 규칙(MESI protocol)같은 다중 코어 캐시의 일관성을 유지하는 규칙이 있음
5.1.5 메모리를 디스크의 캐시로 활용하기
- 디스크는 탐색(seek) 을 위해 10ms 가량의 시간이 소요됨 (메모리 접근 속도가 10만배 가량 빠름)
- 물론 모든 디스크 접근에 탐색이 필요하지는 않음
메모리와 디스크의 속도 차이를 해결하기 위해 둘 사이에 직접 캐시를 추가하면 어떨까?
먼저 레지스터가 메모리의 캐시가 될 수 없는 이유는 레지스터 크기가 한정되어있기 때문. 메모리 용량은 사실 꽤 큰편이라(GB 단위) 어려움
- 최신 운영체제는 분명히 메모리를 디스크의 캐시로 사용
- 일반적으로 메모리 사용률은 100%에 도달하지 않으며 이 여유 공간을 낭비시키지 않도록 디스크의 캐시로 활용하여 디스크에서 데이터 읽어 오는 일을 최소화 함 → 페이지 캐시의 기본원리
결국 CPU의 내부 케시가 메모리 데이터를 저장하고, 메모리가 디스크 데이터를 저장
- 최근 서버에서는 메모리가 디스크를 대체하는 것이 대세 → 메모리 가격이 엄청 저렴해졌기 때문
- AWS에서는 2TB 용량의 메모리를 탑재한 인스턴스도 제공
- Presto, Flink, Spark 같은 메모리 기반 시스템이 디스크 기반의 경쟁자들을 빠르게 대체하고 있음
5.1.6 가상 메모리와 디스크
- 앞서 모든 프로세스가 표준 크기의 자체적인 주소 공간을 가지고 있다고 여러번 이야기 함
- 물리 메모리와는 관련이 없어 물리 메모리의 크기를 초과활 수 있음
Q. 시스템에 프로세스 N개가 실제 물리 메모리를 모두 사용하고 있을 때 새로운 프로세스가 생성되어 N+1번째 프로세스도 메모리를 요청한다면 시스템이 어떻게 처리할까?
A. 디스크는 메모리의 창고 역할을 할 수 있어 자주 사용하지 않은 메모리 데이터를 디스크에 기록하고 데이터가 차지하던 물리 메모리 공간을 해제할 수 있음. 그러면 N+1 번째 프로세스가 다시 메모리를 요청할 수 있음
5.1.7 CPU는 어떻게 메모리를 읽을까?
- CPU가 볼 수 있는 것은 모두 가상 메모리 주소로 실제 물리 메모리 주소로 변환되어야 함
- 변환이 완료되면 캐시를 검색하기 시작하고 캐시에서 찾을 수 없을 때는 메모리에 접근
- 프로세스의 데이터는 디스크에 임시로 보관되어 있을 수 있는데 이때 메모리에서 데이터를 찾을 수 없을 가능성이 있으며 디스크의 프로세스 데이터를 다시 메모리에 적재한 후 메모리를 읽어야 함
- 빅 데이터의 시대가 도래해 단일 장치의 디스크만으로 더이상 데이터를 완전히 저장할 수 없다면 대안은?
5.1.8 분산 저장 지원
- 분산 파일 시스템(distributed file system)을 직접 장착(mount)할 수도 있고, 로컬 디스크는 원격의 분산 파일 시스템에서 전송된 파일을 저장 → 로컬 디스크를 원격의 분산 파일 시스템의 캐시로 간주할 수 있음
- 물론 응답 속도를 높이기 위해 원격 분산 파일 시스템의 데이터를 데이터 흐름(data stream) 형태로 직접 로컬 컴퓨터 시스템의 메모리로 끌어올 수도 있음 (apache kafka)
- 이 경우 대용량 메시지는 원격 분산 파일 시스템에 저장되어 있지만 실시간으로 해당 데이터는 소비자에게 전달되고 이때 메모리를 원격 분산 파일 시스템의 캐시로 간주
'OS' 카테고리의 다른 글
[책리뷰] 컴퓨터 밑바닥의 비밀: ch5.3 다중 스레드 성능 방해자 (0) | 2024.09.22 |
---|---|
[책리뷰] 컴퓨터 밑바닥의 비밀: ch5.2 어떻게 캐시 친화적인 프로그램을 작성할까? (0) | 2024.09.15 |
[책리뷰] 컴퓨터 밑바닥의 비밀: ch4.7 CPU 진화론(중): 축소 명령어 집합의 탄생 (0) | 2024.09.08 |
[책리뷰] 컴퓨터 밑바닥의 비밀: ch4.6 CPU 진화론(상): 복잡 명령어 집합의 탄생 (0) | 2024.09.08 |
[책리뷰] 컴퓨터 밑바닥의 비밀: ch4.2 CPU는 유휴 상태일 때 무엇을 할까? (0) | 2024.09.08 |