ROONTAMS
ROONTAMS
ROONTAMS
전체 방문자
오늘
어제
  • 분류 전체보기 (13)
    • Unity : 개발 (0)
    • 강의 (12)
      • iOS개발 강의 (6)
      • React 강의 (1)
      • 컴퓨터 구조 (5)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

태그

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
ROONTAMS

ROONTAMS

강의/컴퓨터 구조

컴퓨터 구조 개론 - Part 3

2025. 9. 12. 00:39
컴퓨터 구조 개론 - Part 3

컴퓨터 구조 개론

Part 3. 컴퓨터 구조 개괄 및 최신 동향

개요: 컴퓨터는 어떻게 생각할까?

컴퓨터는 생각하지 않는다. 단지 매우 빠르게 계산할 뿐이다. 하지만 초당 수십억 번의 계산을 하다 보니, 마치 생각하는 것처럼 보인다. 이번 파트에서는 컴퓨터가 어떻게 이런 놀라운 일을 해내는지, 그 내부 구조를 뜯어보자.

컴퓨터를 요리사에 비유해보자. CPU는 요리사, 메모리는 도마, 저장장치는 냉장고, 버스는 주방의 통로다. 요리사가 아무리 실력이 좋아도 도마가 작거나, 냉장고가 멀거나, 통로가 좁으면 요리 속도가 느려진다. 컴퓨터도 마찬가지다!

3.1 폰 노이만 구조 깊이 이해하기

3.1.1 CPU: 컴퓨터의 두뇌 해부하기

CPU(Central Processing Unit)는 컴퓨터의 두뇌다. 하지만 인간의 뇌와 달리, CPU는 한 번에 하나씩만 처리한다. 대신 엄청나게 빨리 처리해서 동시에 여러 일을 하는 것처럼 보인다.

CPU 내부 구조

그림 3.1: CPU 내부 구조 - ALU, 제어장치, 레지스터의 관계

CPU의 주요 구성요소:

  • ALU (Arithmetic Logic Unit): 실제 계산을 하는 곳
    • 산술 연산: 덧셈, 뺄셈, 곱셈, 나눗셈
    • 논리 연산: AND, OR, NOT, XOR
    • 비교 연산: 크다, 작다, 같다
  • 제어장치 (Control Unit): 지휘자 역할
    • 명령어 해석
    • 다른 부품에 신호 전달
    • 타이밍 조절
  • 레지스터 (Register): CPU의 작은 주머니
    • 범용 레지스터: 계산용 임시 저장
    • PC (Program Counter): 다음 명령어 주소
    • SP (Stack Pointer): 스택 위치
    • 상태 레지스터: 계산 결과 상태 (0인지, 음수인지 등)

🔍 간단한 덧셈의 여정

3 + 5를 계산한다고 해보자:

  1. 메모리에서 3을 레지스터 A로 가져옴 (LOAD)
  2. 메모리에서 5를 레지스터 B로 가져옴 (LOAD)
  3. ALU가 A와 B를 더함 (ADD)
  4. 결과 8을 레지스터 C에 저장
  5. C의 값을 메모리로 보냄 (STORE)

이 5단계가 나노초(10억분의 1초) 단위로 일어난다!

3.1.2 메모리: 작업 공간의 비밀

메모리는 CPU의 작업 공간이다. 책상이 넓으면 여러 책을 펼쳐놓고 공부할 수 있듯이, 메모리가 크면 여러 프로그램을 동시에 실행할 수 있다.

메모리의 특징:

  • 휘발성: 전원이 꺼지면 내용이 사라짐
  • 빠른 접근: 어느 위치든 같은 속도로 접근 (Random Access)
  • 바이트 단위 주소: 각 바이트마다 고유 주소 부여
메모리 주소 저장된 값 의미
0x0000 0x48 'H' (ASCII)
0x0001 0x65 'e' (ASCII)
0x0002 0x6C 'l' (ASCII)
0x0003 0x6C 'l' (ASCII)
0x0004 0x6F 'o' (ASCII)

메모리 주소는 보통 16진수로 표현한다. 0x는 16진수를 의미하고, 한 자리가 4비트를 나타내므로 두 자리(8비트 = 1바이트)씩 묶어서 표현한다.

3.1.3 버스: 정보의 고속도로

버스(Bus)는 CPU, 메모리, 입출력장치를 연결하는 통로다. 도로가 넓으면 많은 차가 다닐 수 있듯이, 버스가 넓으면 한 번에 많은 데이터를 전송할 수 있다.

3종류의 버스:

  1. 데이터 버스: 실제 데이터가 이동
    • 너비: 8비트, 16비트, 32비트, 64비트
    • 예: 64비트 버스 = 한 번에 8바이트 전송
  2. 주소 버스: 데이터의 위치 정보
    • 너비가 메모리 최대 용량 결정
    • 32비트 = 2^32 = 4GB까지 주소 지정
    • 64비트 = 2^64 = 16EB까지 (실제로는 48비트만 사용)
  3. 제어 버스: 읽기/쓰기 신호
    • 메모리 읽기/쓰기
    • I/O 읽기/쓰기
    • 인터럽트 신호

버스 비유: 택배 시스템

데이터 버스 = 택배 트럭 (물건 운반)
주소 버스 = 주소 정보 (어디로 갈지)
제어 버스 = 배송 지시 (받기/보내기)

트럭이 크면(버스 폭이 넓으면) 한 번에 많이 실을 수 있고, 주소 체계가 세밀하면(주소 버스가 넓으면) 더 많은 곳에 배달할 수 있다!

3.2 CPU는 어떻게 일할까?

3.2.1 명령어 사이클: Fetch-Decode-Execute

CPU는 단순한 일을 반복한다. 명령어를 가져오고(Fetch), 해석하고(Decode), 실행한다(Execute). 이것을 명령어 사이클이라 한다.

명령어 사이클의 단계:
1. Fetch (인출): 메모리에서 명령어 가져오기
2. Decode (해독): 명령어가 무엇인지 해석
3. Execute (실행): 실제로 명령 수행
4. Store (저장): 결과를 메모리에 저장 (필요시)
// CPU 동작을 시뮬레이션하는 의사 코드
while (power_on) {
    // 1. Fetch: PC가 가리키는 명령어 가져오기
    instruction = memory[PC];
    PC = PC + 1;
    
    // 2. Decode: 명령어 해석
    opcode = extract_opcode(instruction);
    operands = extract_operands(instruction);
    
    // 3. Execute: 명령어 종류에 따라 실행
    switch (opcode) {
        case ADD:
            result = register[operands[0]] + register[operands[1]];
            register[operands[2]] = result;
            break;
        case LOAD:
            register[operands[0]] = memory[operands[1]];
            break;
        case STORE:
            memory[operands[1]] = register[operands[0]];
            break;
        case JUMP:
            PC = operands[0];
            break;
    }
}

3.2.2 파이프라인: 조립 라인처럼 일하기

현대 CPU는 여러 명령어를 동시에 처리한다. 마치 세탁소에서 세탁-건조-다림질을 동시에 다른 옷에 대해 진행하는 것처럼!

CPU 파이프라인

그림 3.2: 5단계 파이프라인 - 동시에 5개 명령어 처리

시간 Fetch Decode Execute Memory Write
1 명령어1 - - - -
2 명령어2 명령어1 - - -
3 명령어3 명령어2 명령어1 - -
4 명령어4 명령어3 명령어2 명령어1 -
5 명령어5 명령어4 명령어3 명령어2 명령어1

파이프라인 덕분에 이론적으로 5배 빨라질 수 있다! 하지만 실제로는 여러 문제가 있다:

  • 데이터 해저드: 이전 명령어 결과가 필요한 경우
  • 제어 해저드: 분기(if문) 때문에 다음 명령어가 불확실
  • 구조적 해저드: 같은 자원을 동시에 사용하려는 경우
⚠️ 파이프라인의 함정: if문이 많은 코드는 파이프라인 효율이 떨어진다. CPU가 다음 명령어를 예측했다가 틀리면(분기 예측 실패), 파이프라인을 비우고 다시 시작해야 한다. 게임 프로그래밍에서 if문을 줄이려는 이유가 여기에 있다!

3.2.3 캐시: CPU의 주머니

CPU는 빠른데 메모리는 느리다. 이 속도 차이를 극복하기 위해 캐시(Cache)를 사용한다. 자주 쓰는 물건을 주머니에 넣고 다니는 것처럼!

캐시 계층 구조:

레벨 크기 속도 위치 용도
레지스터 수십 바이트 1 사이클 CPU 내부 즉시 사용할 데이터
L1 캐시 32-64 KB 3-4 사이클 각 코어 내부 자주 쓰는 명령어/데이터
L2 캐시 256-512 KB 10-20 사이클 각 코어 전용 L1에서 못 찾은 것
L3 캐시 8-32 MB 20-40 사이클 모든 코어 공유 L2에서 못 찾은 것
메인 메모리 8-32 GB 100+ 사이클 메인보드 모든 데이터

📚 캐시를 도서관에 비유하면

레지스터 = 손에 든 책 (바로 읽기)
L1 캐시 = 책상 위 (팔만 뻗으면 됨)
L2 캐시 = 책장 (일어나서 가져오기)
L3 캐시 = 같은 층 서가 (걸어가기)
메모리 = 다른 층 서고 (엘리베이터 타기)
디스크 = 외부 창고 (차 타고 가기)

캐시의 작동 원리:

  1. 시간 지역성: 최근 사용한 데이터는 또 사용할 확률이 높다
  2. 공간 지역성: 근처 데이터도 곧 사용할 확률이 높다
// 캐시 친화적인 코드 vs 비친화적인 코드

// 나쁜 예: 캐시 미스 많음 (열 우선 접근)
for (j = 0; j < 1000; j++) {
    for (i = 0; i < 1000; i++) {
        sum += array[i][j];  // 메모리 점프!
    }
}

// 좋은 예: 캐시 히트 많음 (행 우선 접근)
for (i = 0; i < 1000; i++) {
    for (j = 0; j < 1000; j++) {
        sum += array[i][j];  // 연속된 메모리!
    }
}
💡 프로그래밍 팁: 배열을 순차적으로 접근하면 캐시 효율이 좋다. C/C++는 행 우선(row-major), Fortran은 열 우선(column-major) 저장이다. 언어의 특성을 알고 코드를 작성하면 성능이 10배 이상 차이날 수 있다!

3.3 최신 프로세서 이야기

3.3.1 Intel vs AMD vs Apple Silicon

CPU 시장은 오랫동안 Intel이 지배했지만, 최근 AMD와 Apple이 혁신적인 제품으로 판도를 바꾸고 있다.

제조사 최신 제품 특징 장단점
Intel Core i9-14900K • P코어 + E코어
• 최대 6GHz
• x86-64
✓ 높은 클럭
✓ 게임 성능
✗ 전력 소비
AMD Ryzen 9 7950X • 칩렛 설계
• 3D V-Cache
• x86-64
✓ 멀티코어 성능
✓ 가성비
✗ 싱글코어
Apple M3 Max • ARM 기반
• 통합 메모리
• SoC 설계
✓ 전력 효율
✓ 통합 성능
✗ 호환성
2020년 Apple이 Intel을 버리고 자체 칩을 만들겠다고 했을 때, 많은 사람이 의심했다. 스마트폰 칩 만드는 회사가 무슨 PC 칩을? 하지만 M1이 나오자 모두가 놀랐다. Intel 칩보다 빠르면서도 배터리는 2배 오래 갔다. 이것이 가능했던 비결은?

Apple Silicon의 혁신:

  • 통합 메모리 아키텍처: CPU, GPU가 메모리 공유
  • 전용 가속기: Neural Engine, ProRes 코덱 등
  • 효율 코어 + 성능 코어: 작업에 따라 선택 사용
  • 5nm 공정: 더 작고 효율적인 트랜지스터

3.3.2 코어가 많으면 정말 빠를까?

"코어가 2배면 속도도 2배?" 안타깝게도 그렇지 않다. 암달의 법칙(Amdahl's Law)이 이를 설명한다.

암달의 법칙:
프로그램의 일부만 병렬화 가능하다면, 코어를 아무리 늘려도 속도 향상에는 한계가 있다.

예: 프로그램의 50%만 병렬화 가능하다면,
• 2코어: 1.33배 빨라짐
• 4코어: 1.6배 빨라짐
• 무한 코어: 최대 2배까지만 빨라짐

멀티코어가 유리한 작업:

  • 동영상 인코딩 (각 프레임 독립 처리)
  • 3D 렌더링 (픽셀별 독립 계산)
  • 과학 시뮬레이션 (영역 분할)
  • 웹 서버 (요청별 독립 처리)

멀티코어가 불리한 작업:

  • 게임 (순차적 로직이 많음)
  • 오피스 작업 (단일 스레드 위주)
  • 웹 브라우징 (UI는 단일 스레드)

3.3.3 AI 칩은 뭐가 다를까?

AI 계산은 주로 행렬 곱셈이다. CPU는 범용적이라 행렬 곱셈이 비효율적이다. 그래서 전용 칩이 나왔다.

CPU vs GPU vs TPU

특징 CPU GPU TPU/NPU
설계 목적 범용 계산 그래픽/병렬 AI 전용
코어 수 4-64개 수천 개 수만 개
코어 복잡도 매우 복잡 단순 특화
적합한 작업 순차 처리 병렬 처리 행렬 연산
// 행렬 곱셈: CPU vs GPU 차이

// CPU 방식: 순차적으로 하나씩
for (i = 0; i < N; i++) {
    for (j = 0; j < N; j++) {
        for (k = 0; k < N; k++) {
            C[i][j] += A[i][k] * B[k][j];
        }
    }
}
// 시간 복잡도: O(N³)

// GPU 방식: 모든 (i,j)를 동시에
// 각 스레드가 C[i][j] 하나씩 계산
__global__ void matrixMul(A, B, C) {
    i = threadIdx.x;
    j = threadIdx.y;
    
    for (k = 0; k < N; k++) {
        C[i][j] += A[i][k] * B[k][j];
    }
}
// N²개 스레드가 동시 실행!

AI 칩의 특별한 기능들:

  • Tensor Core: 4x4 행렬을 한 번에 곱셈
  • Mixed Precision: FP16으로 계산, FP32로 누적
  • Sparsity: 0이 많은 행렬 최적화
  • 메모리 대역폭: HBM으로 초고속 데이터 전송
💡 미래 전망: 2030년에는 모든 컴퓨터에 AI 칩이 기본 탑재될 것이다. 지금의 GPU처럼 AI 가속기가 표준이 되고, 일반 프로그램도 AI 기능을 활용하게 될 것이다. 프로그래머는 CPU, GPU, NPU를 모두 활용하는 이기종 컴퓨팅(Heterogeneous Computing)을 배워야 한다!

3.4 프로그래머가 꼭 알아야 할 하드웨어 지식

3.4.1 메모리 정렬과 패딩

CPU는 메모리를 특정 단위로 읽는 것을 좋아한다. 4바이트 정수는 4의 배수 주소에, 8바이트 실수는 8의 배수 주소에 있을 때 가장 빠르게 읽을 수 있다.

// 구조체 패딩 예제
struct BadLayout {
    char a;     // 1바이트
    int b;      // 4바이트 (3바이트 패딩 추가됨!)
    char c;     // 1바이트
    double d;   // 8바이트 (7바이트 패딩 추가됨!)
};  // 총 크기: 24바이트 (10바이트 낭비)

struct GoodLayout {
    double d;   // 8바이트
    int b;      // 4바이트
    char a;     // 1바이트
    char c;     // 1바이트
    // 2바이트 패딩
};  // 총 크기: 16바이트 (2바이트만 낭비)

3.4.2 분기 예측과 최적화

현대 CPU는 if문의 결과를 예측한다. 예측이 맞으면 빠르고, 틀리면 파이프라인을 비워야 해서 느려진다.

// 분기 예측 실험
// 느린 코드: 예측 불가능한 패턴
for (i = 0; i < N; i++) {
    if (random_array[i] > 128) {  // 50% 확률, 예측 어려움
        sum += random_array[i];
    }
}

// 빠른 코드: 예측 가능한 패턴
sort(sorted_array);  // 먼저 정렬!
for (i = 0; i < N; i++) {
    if (sorted_array[i] > 128) {  // 앞은 false, 뒤는 true
        sum += sorted_array[i];
    }
}
// 정렬된 배열이 2-6배 빠를 수 있다!

3.4.3 SIMD: 한 번에 여러 개 계산하기

SIMD(Single Instruction Multiple Data)는 하나의 명령으로 여러 데이터를 동시에 처리한다. 벡터 연산에 매우 효과적이다.

// SIMD를 활용한 벡터 덧셈
// 일반 방식: 하나씩 더하기
for (i = 0; i < 1000; i++) {
    c[i] = a[i] + b[i];
}

// SIMD 방식: 4개씩 한번에 (SSE 사용)
for (i = 0; i < 1000; i += 4) {
    __m128 va = _mm_load_ps(&a[i]);  // 4개 float 로드
    __m128 vb = _mm_load_ps(&b[i]);  // 4개 float 로드
    __m128 vc = _mm_add_ps(va, vb);  // 4개 동시 덧셈!
    _mm_store_ps(&c[i], vc);         // 4개 float 저장
}
// 이론상 4배 빠름!

정리

컴퓨터 구조를 이해하는 것은 단순히 하드웨어를 아는 것이 아니다. 효율적인 프로그램을 작성하고, 성능 문제를 해결하고, 새로운 기술을 활용하는 데 필수적인 지식이다.

핵심 요점:

  1. 폰 노이만 구조는 여전히 현대 컴퓨터의 기본
  2. CPU는 단순한 일을 매우 빠르게 반복
  3. 메모리 계층을 이해하면 빠른 프로그램을 만들 수 있음
  4. 파이프라인과 캐시가 성능의 핵심
  5. 멀티코어는 만능이 아님 (암달의 법칙)
  6. AI 가속기는 특정 연산에 특화
  7. 하드웨어 특성을 고려한 프로그래밍이 중요
💡 마지막 조언: 하드웨어는 계속 발전하지만, 기본 원리는 변하지 않는다. 폰 노이만 구조, 메모리 계층, 파이프라인, 캐시 같은 개념은 50년 전에도 있었고, 앞으로도 계속 있을 것이다. 이런 기본기를 탄탄히 하면, 새로운 기술도 쉽게 이해할 수 있다. 컴퓨터는 복잡해 보이지만, 결국 0과 1을 빠르게 처리하는 기계일 뿐이다!

'강의 > 컴퓨터 구조' 카테고리의 다른 글

데이터의 표현 - Part2  (0) 2025.09.19
데이터의 표현 - Part1  (0) 2025.09.19
컴퓨터 구조 개론 - Part 2  (0) 2025.09.12
컴퓨터 구조 개론 - Part 1  (0) 2025.09.12
    '강의/컴퓨터 구조' 카테고리의 다른 글
    • 데이터의 표현 - Part2
    • 데이터의 표현 - Part1
    • 컴퓨터 구조 개론 - Part 2
    • 컴퓨터 구조 개론 - Part 1
    ROONTAMS
    ROONTAMS

    티스토리툴바