serversim
학습시뮬레이터템플릿가격
…
…
메뉴 열기
학습↗시뮬레이터↗템플릿↗가격↗
내 Documents문서
목차/2단원2 / 16

코드 한 줄은 어떻게 실행되나

우리가 쓴 코드 한 줄은 CPU 안에서 정확히 어떻게 실행될까요? CPU는 만능 기계가 아니라 버튼이 몇 개 안 되는 리모컨이어서, 한 줄이 버튼 여러 번으로 쪼개집니다.

컴퓨터는 결국 아주 빠른 계산기입니다. 우리가 작성한 코드는 컴파일이나 해석을 거쳐 CPU가 이해하는 아주 단순한 명령들의 목록이 되고, CPU는 그 목록을 위에서부터 하나씩 실행합니다. 이 단원에서는 그 "하나씩"이 실제로 어떤 순서로 일어나는지, 함수를 호출하면 무엇이 어디에 기록되는지, 그리고 데이터가 메모리 어디에 놓이는지를 봅니다. 아래 애니메이션을 단계 버튼으로 직접 넘겨보면서 읽으면 가장 좋습니다.

① CPU가 하는 일은 사실 세 가지뿐

CPU는 (1) 다음에 실행할 명령을 메모리에서 가져오고(인출), (2) 그게 무슨 뜻인지 해석하고, (3) 실행합니다. 이 세 가지를 초당 수십억 번 반복하는 것이 전부입니다. 우리가 "프로그램이 돈다"고 부르는 현상은 이 반복이 빠르게 이어지는 것뿐입니다.

② 메모리는 번호가 붙은 사물함

메모리는 1바이트짜리 칸이 길게 늘어선 것이고, 각 칸에는 0번, 1번, 2번… 하는 번호가 붙어 있습니다. 이 번호를 주소라고 부릅니다. CPU는 "몇 번 칸의 값을 가져와라", "몇 번 칸에 이 값을 넣어라" 같은 식으로만 메모리를 다룹니다. 변수 이름은 사람이 쓰기 편하라고 붙인 이름표일 뿐, 실제로는 전부 주소로 번역됩니다.

③ 레지스터 — CPU 안에 있는 아주 작은 작업대

메모리는 CPU 입장에서 꽤 먼 곳입니다(수십~수백 배 느립니다). 그래서 CPU 안에는 값 몇 개만 담아두는 초고속 저장소가 있는데, 이것이 레지스터입니다. 그중 특별한 레지스터 하나가 PC(프로그램 카운터)로, "다음에 실행할 명령이 몇 번 줄(주소)인지"를 담고 있습니다. 오른쪽 패널에서 PC 값이 바뀌는 걸 보면, 실행이 어디로 흘러가는지가 그대로 보입니다.

④ 스택 — 함수 호출을 위한 임시 작업 공간

함수를 호출하면 그 함수의 지역변수를 놓을 자리가 필요합니다. 이 자리를 스택 프레임이라고 하고, 호출할 때 쌓고(push) 끝나면 걷어냅니다(pop). 접시를 쌓듯 마지막에 올린 것이 먼저 내려오기 때문에 스택(더미)이라고 부릅니다. 중요한 건 프레임에 지역변수만 들어가는 게 아니라는 점입니다 — "이 함수가 끝나면 돌아갈 주소"도 함께 적힙니다. return이 어디로 돌아갈지 아는 비밀이 바로 이것입니다.

⑤ 힙 — 크고 오래 사는 데이터의 창고

배열이나 객체처럼 크기가 크거나, 함수가 끝난 뒤에도 살아 있어야 하는 데이터는 스택에 두기 곤란합니다(프레임이 사라지면 같이 사라지니까요). 그래서 이런 데이터는 힙이라는 별도 영역에 놓고, 스택에는 그 데이터가 있는 위치만 적어둡니다. 이 페이지에서는 힙 상자마다 @1, @2 같은 주소표를 붙이고 스택 변수는 그 번호만 들게 그렸습니다. 스택의 @1과 힙 상자의 @1이 같은 번호인지 확인하며 보세요.

단계 1/9속도
program
1main() {
2 prices = [12000, 8000]PC ◀
3 total = sum(prices)
4 print(total)
5}
6sum(list) {
7 t = 0
8 for n in list: t += n
9 return t
10}

실행은 main의 첫 줄에서 시작합니다 — 아래의 sum(6~10번 줄)은 "정의"일 뿐, 호출되기 전엔 실행되지 않습니다. CPU는 PC(프로그램 카운터) 레지스터에 "지금 실행할 줄"을 들고 있습니다: PC = 2. 배열 실물은 힙 상자에 담기고 주소표 @1이 붙습니다. 스택의 prices에는 그 번호만 적힙니다.

CPU0
상태실행 중PC · 실행 위치→ 2번 줄
스택↑ 위가 최근 프레임
main()
prices = @1
힙
@1Array [12000, 8000]

시뮬레이터에서 해보기

  1. 1.같은 '3-tier 기본' 프리셋 — Spring 카드를 클릭하면 기본 1,000 RPS에서 CPU 63%입니다. 이 숫자가 바로 지금 이 단원에서 본 '명령어가 한 줄씩 실행되는' 결과입니다.
  2. 2.RPS 슬라이더를 올려 요청을 늘리면 초당 실행해야 할 명령어 총량이 늘어나고, CPU 게이지가 같이 올라갑니다 — 코드 실행과 CPU 사용률의 관계를 직접 눈으로 확인하세요.
시뮬레이터에서 실험해보기 →

이 단원의 용어

명령(instruction)
CPU가 한 번에 처리하는 가장 작은 작업 단위. "더해라", "이 값을 저기로 옮겨라" 수준.
주소(address)
메모리 칸에 붙은 번호. 변수 이름은 결국 주소로 번역된다.
레지스터(register)
CPU 안의 초고속 저장소. 개수가 아주 적고, 지금 계산에 쓰는 값만 올려둔다.
PC (프로그램 카운터)
다음에 실행할 명령의 주소를 담은 특별한 레지스터. "실행 위치".
스택 프레임
함수 하나가 쓰는 임시 공간. 지역변수 + 복귀 주소가 들어간다. 호출 시 쌓이고 return 시 사라진다.
힙(heap)
크거나 오래 사는 데이터를 놓는 메모리 영역. 스택은 그 위치(주소)만 든다.
참조(reference)
값 자체가 아니라 "값이 있는 곳의 주소"를 들고 있는 것. 이 페이지의 @1 표기.

호출 = 복귀 주소 등록 + 점프. return = 그 주소로 복귀.

남은 문제

그런데 힙에 놓인 상자들은 언제, 누가 치울까요? 프로그램을 오래 켜두면 메모리는 왜 점점 찰까요? →

← 이전 단원

1단원. 컴퓨터는 무엇으로 되어 있나

다음 단원 →

3단원. 스택과 힙 — 무엇이 어디에 쌓이나