일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 힙
- 이진탐색
- 다대일
- BOJ
- CHECK OPTION
- shared lock
- 다대다
- 지연로딩
- 비관적락
- querydsl
- eager
- 스토어드 프로시저
- JPQL
- 연결리스트
- SQL프로그래밍
- 연관관계
- 낙관적락
- dfs
- 즉시로딩
- 유니크제약조건
- PS
- execute
- 동적sql
- 스프링 폼
- FetchType
- 데코레이터
- fetch
- 백트래킹
- exclusive lock
- 일대다
- Today
- Total
흰 스타렉스에서 내가 내리지
캐시 (cache) 본문
def sum(arr):
total = 0 # 1
for a in arr: # 2
total += a # 3
return total
#3 라인에서, CPU는 for문이 수행될 때 배열의 모든 원소를 가져오면서 항상 total값을 먼저 가져온다.
이처럼 한번 접근한 변수는 계속해서 접근할 가능성이 높다는 것이 시간 지역성(temporal locality)이다.
# 2 라인에서, 다음에 접근할 배열의 원소는 이전에 접근한 원소의 바로 다음이다.
이처럼 이번에 접근할 배열의 원소는 이전에 접근할 변수 근처에 있을 가능성이 높다는 것이 공간 지역성(sptial locality) 이다.
이런 '지역성의 원리'로 인해 CPU와 메인 메모리 사이에 캐시를 두게 되었다.
CPU 안에는 메인 메모리에서 가져온 데이터를 일시적으로 저장할 수 있는 메모리 공간인 레지스터가 존재한다.
레지스터는 아주 빨라서 CPU의 데이터 요청이 들어오면 1클럭만에 데이터를 ALU(Arithmetic Logic Unit, 산술 논리 장치. CPU 연산장치이다)로 보낼 수 있다.
반면에 메모리에서 데이터를 가져올 때는 20~100클럭이 소요된다.
메인 메모리에 있는 변수는 연산을 하기 전후에 반드시 레지스터를 거친다.
total 변수, a 변수 (内 Main Memory) → 레지스터 (内 CPU) → ALU (内 CPU) → 임시 레지스터 {새로운 total 변수} (内 CPU) → 새로운 total 변수 (内 Main Memory)
즉, # 3 라인의 코드가 실행되면,
- CPU는 매번 메인 메모리에 저장된 total 값을 레지스터로 가져온다.
- arr에서 한 요소를 매번 레지스터로 옮긴다.
- 두 값을 더해 다시 레지스터에 저장한다.
- 그 값을 메인 메모리의 total에 저장한다.
이를 위해 total 값을 가져오는데 20클럭, 배열의 한 요소를 가져오는데 20클럭, 결과값을 메인메모리로 옮기는데 20클럭이 소요된다.
실제 덧셈 연산을 하는데는 1클럭 밖에 안걸리는데, 매우 비효율적인 작업들이 추가로 수행되는 것을 볼 수 있다.
효율성을 높이기 위한 캐시(Cache)
캐시 : CPU와 메인 메모리 사이에 성능이 빠른 버퍼로 메모리를 둔 것
CPU는 이제 데이터를 메인 메모리 대신 캐시에 요청을 한다.
캐시에 해당 데이터가 없으면, 메인 메모리에서 해당 데이터 뿐만 아니라 주변 변수까지 한꺼번에 가져온다.
예를 들어, arr[1]을 캐시에 요청했을 때 해당 데이터가 캐시에 존재하지 않으면, 캐시는 메인 메모리에서 arr[0], arr[1], arr[2]와 같이 주변 변수까지 가져와 저장한다. 지역성의 원리를 활용한 것이다.
CPU가 캐시에 요청했는데 요청한 데이터가 없다면 이를 캐시 미스(cache miss)라고 하며, 데이터가 있으면 캐시 히트(cache hit)라고 한다.
CPU가 데이터를 캐시에서 가져올 때 걸리는 시간은 3클럭으로, 메인 메모리에서 가져오는 것 보다 훨씬 빠르다.
공간 지역성을 고려한다면, 캐시 히트가 발생했을 때 성능은 월등하게 향상된다.
'Data Structure' 카테고리의 다른 글
[자료구조] 큐와 원형 큐 (Queue, Circular Queue) (0) | 2022.01.02 |
---|---|
[자료구조] 더미 이중 연결 리스트 (Dummy Double Linked List) (0) | 2022.01.01 |
[자료구조] 스택 (Stack) (0) | 2022.01.01 |
[자료구조] 동적 배열과 연결리스트의 차이 (0) | 2022.01.01 |
[자료구조] 재귀 함수를 호출할 때 (0) | 2021.12.30 |