CPU와 Memory간 데이터 교환 방식
CPU는 직접 메모리에 접근하지 않고, System bus를 통해 메모리(RAM)와 데이터를 주고받음.
주요 흐름
- CPU가 주소를 지정 (주소 버스 사용)
- 해당 주소의 데이터를 요청 (제어 버스 사용)
- RAM이 데이터를 반환 (데이터 버스 사용)
- CPU가 연산 수행
데이터 교환 속도를 높이기 위한 장치
RAM과 CPU간 속도 차이가 커서, 효율적인 데이터 흐름을 위해 사용되는 장치/기술들
| 장치/기술 | 역할 |
|---|
| 캐시 메모리 (L1/L2/L3) | CPU와 RAM 사이에 있는 초고속 메모리. 자주 쓰는 데이터를 저장해 CPU 접근 속도 향상 |
| DMA (Direct Memory Access) | CPU를 거치지 않고 장치 ↔ 메모리 간 직접 전송 |
| MMU (Memory Management Unit) | 가상 주소 ↔ 물리 주소 변환. 메모리 보호 및 관리 |
| 프리페칭(prefetching) | CPU가 사용할 데이터를 미리 캐시에 로딩 |
| 버스 인터리빙(Bus Interleaving) | 병렬 버스를 사용해 데이터 전송 병목을 해소 |
Bus
Bus는 CPU와 메모리, 주변 장치간 데이터를 전달하는 통로(전선 묶음)
Bus의 주요 종류
| 종류 | 역할 |
|---|
| Address Bus | CPU가 데이터를 읽거나 쓸 메모리 주소를 지정 |
| Data Bus | 실제 데이터 전송을 담당 |
| Control Bus | 읽기/쓰기 신호, 인터럽트 등 제어 신호 전달 |
기타 System Bus
- System Bus: CPU, RAM, Chipset 등 주요 부품 연결
- I/O Bus: 주변장치(키보드, 저장장치 etc) 연결 ex) PCle, USB etc
- Front-Side-Bus(FSB): 예전 시스템에서 CPU와 메인 메모리 연결 역할
Bus를 통해 연결되는 장치들
Bus는 단순히 CPU와 RAM만이 아니라 다양한 장치 연결
| 장치 | 연결 목적 |
|---|
| 스토리지 (SSD, HDD) | 저장소에서 데이터 읽기/쓰기 |
| GPU | 그래픽 연산 처리 |
| I/O 장치 (마우스, 키보드, 터치) | 사용자 입력 수신 |
| 네트워크 카드 | 외부 통신 |
| 사운드 카드, 카메라 등 | 멀티미디어 처리 |
이들 장치들도 대부분 버스를 통해 CPU와 간접적으로 데이터 교환
Cache Memory
Cache Memory는 CPU 내부 또는 근접한 위치에 있는 소용량, 초고속 메모리
역할
- CPU가 자주 접근하는 데이터나 명령어를 미리 저장
- RAM보다 수십~수백배 빠르므로, 속도 병목 완화
Cache 계층 구조
| 계층 | 위치 | 속도 | 크기 |
|---|
| L1 캐시 | CPU 코어 내 | 매우 빠름 | 수십 KB |
| L2 캐시 | CPU 코어 또는 공유 | 빠름 | 수백 KB~MB |
| L3 캐시 | 코어 간 공유 | 느림 (RAM보다는 빠름) | 수 MB |
Cache Hit & Cache Miss
| 개념 | 설명 | 성능 영향 |
|---|
| Cache Hit | CPU가 원하는 데이터가 이미 캐시에 있음 | ✅ 매우 빠름 |
| Cache Miss | CPU가 원하는 데이터가 캐시에 없음 → RAM에서 가져와야 함 | ❌ 느림 (RAM 접근 필요) |
Cache Miss가 자주 발생하면 실행 속도가 현저히 느려짐
iOS의 Cache 관련 도구들
NSCache - Memory 기반 Cache
- NSCache는 in-memory cache로, Dictionary와 비슷하게 key-value 형식으로 데이터 저장
- 하지만 Dictionary와 달리, 자동으로 메모리 압박 시 Cache 제거(didReceiveMemoryWarning 대응)
- thread-safe (multi thread 환경에서도 안전)
주요 특징
| 특징 | 설명 |
|---|
| 메모리 자동 관리 | 시스템이 메모리 부족하면 자동으로 객체 제거 (LRU 기반) |
| thread-safe | 동시 접근에 안전 |
| delegate 없이 간단 사용 | 별도 설정 없이 사용 가능 |
| cost 설정 가능 | 객체마다 메모리 비용(cost)을 설정하여 캐시 제한 관리 가능 |
예시 코드
let imageCache = NSCache<NSString, UIImage>()
func loadImage(for url: URL, completion: @escaping (UIImage?) -> Void) {
if let cachedImage = imageCache.object(forKey: url.absoluteString as NSString) {
completion(cachedImage)
return
}
URLSession.shared.dataTask(with: url) { data, _, _ in
if let data = data, let image = UIImage(data: data) {
imageCache.setObject(image, forKey: url.absoluteString as NSString)
completion(image)
}
}.resume()
}
URLCache - Network 응답 Cache
- URLCache는 HTTP(S) 요청의 응답을 저장하여, 같은 요청에 대해 서버와 다시 통신하지 않고 로컬에서 응답
- 기본적으로 URLSession과 연동되어 동작
- 디스크/메모리 양쪽에 캐시 저장 가능
Cache 저장 조건
- 응답 헤더에 Cache-Control, ETag, Expires 등 캐시 가능 지시자가 있어야함
- URLSessionConfiguration의 urlCache 속성에 캐시 설정이 되어 있어야함
예시 코드
let memoryCapacity = 50 * 1024 * 1024 // 50MB
let diskCapacity = 100 * 1024 * 1024 // 100MB
let cache = URLCache(memoryCapacity: memoryCapacity, diskCapacity: diskCapacity, diskPath: "myCache")
let config = URLSessionConfiguration.default
config.urlCache = cache
config.requestCachePolicy = .returnCacheDataElseLoad
let session = URLSession(configuration: config)
Cache 정책 (requestCachePolicy)
| 정책 | 설명 |
|---|
| .useProtocolCachePolicy | 응답 헤더에 따른 기본 정책 |
| .reloadIgnoringLocalCacheData | 항상 새로 요청, 캐시 무시 |
| .returnCacheDataElseLoad | 캐시가 있으면 사용, 없으면 네트워크 요청 |
| .returnCacheDataDontLoad | 캐시만 사용, 네트워크 요청 안 함 |
NSCache or URLCache?
| 상황 | 적합한 캐시 |
|---|
| 이미지, 오브젝트 캐시 | NSCache |
| HTTP 응답 캐시 (JSON, HTML, 이미지 등) | URLCache |
| 사용자 정의 리소스 캐싱 | NSCache (데이터 타입 자유로움) |
| 시스템 기반 자동 캐싱 활용 | URLCache (Cache-Control 기반) |
팁
- NSCache는 메모리 기반, URLCache는 네트워크 기반 캐시라는 점이 핵심
- 이미지 앱에서는 Kingfisher, SDWebImage 등 라이브러리가 내부적으로 둘다 활용
- NSCache는 ViewModel 내부에서 UIImage, NSData, Custom Object 등을 캐싱하는데 유용