코드 3-1을 살펴보겠습니다.
코드 3-1 principle_of_locality.py
def sum_all(arr):
ret = 0 # 1
for elem in arr: # 2
ret += elem # 3
return ret
프로그램을 작성하다 보면 이런 방식의 코드를 자주 접합니다. 연산 결과를 축적하는 ret 변수와 리스트에서 모든 요소를 하나씩 가져와 저장하는 elem 변수가 있습니다. ret 변수를 생각해 봅시다. CPU는 for 문이 수행될 때 배열의 모든 요소를 가져오면서 항상 ret 값을 먼저 가져옵니다. 이처럼 한번 접근한 변수는 계속해서 접근할 가능성이 높다는 것이 시간 지역성(temporal locality)입니다. 이번에는 배열의 요소를 생각해 봅시다. # 2 라인을 보면, 이번에 접근한 배열의 요소는 이전에 접근한 요소의 바로 다음이라는 것을 알 수 있지요. 이처럼 이번에 접근한 변수는 이전에 접근한 변수 근처에 있을 가능성이 높다는 것이 공간 지역성(spatial locality)입니다. 이런 지역성의 원리가 CPU와 메인 메모리 사이에 캐시를 두게 된 이유입니다.
코드 3-1에서는 # 1에 있는 ret 변수에 # 2의 arr에서 요소를 하나씩 가져와 ret에 더하고 있습니다. # 3 라인이 실행될 때 어떤 일이 일어나는지 한번 고민해 봅시다. CPU에는 메인 메모리에서 가져온 데이터를 일시적으로 저장할 수 있는 메모리 공간인 레지스터가 존재합니다. 이 레지스터는 그 어떤 메모리보다 빠르기 때문에 CPU가 값을 요청했을 때 1클럭 만에 데이터를 CPU 연산 장치인 ALU(Arithmetic Logic Unit)(산술 논리 장치)로 보낼 수 있습니다. 반면, 메모리에서 데이터를 가져올 때는 20~100클럭 정도가 소요됩니다.