
컴퓨터 아키텍처란, 컴퓨터의 여러 구성요소를 배치하는 방법을 뜻한다.
메무리와 관련한 구조 개선에 대해 알아보자
ㅁ 기본적인 구조 요소들
가장 흔한 두 가지 컴퓨터 구조는 폰 노이만 구조와 하버드 구조다.
각 구조는 메모리 배열에서만 차이가 난다.
폰 노이만 구조는 메모리가 하나 뿐이고,
하버드 구조는 명렁어 메모리와 데이터 메모리가 별도로 존재한다.
따라서 폰 노이만 구조가 조금 더 느리지만, 데이터 버스와 주소 버스가 하나만 존재한다.
- 프로세스 코어
두 구조 모두 CPU가 하나 뿐이지만,
1980년대 등장한 멀티프로세서 시스템은 여러 CPU를 활용한다.
여러 CPU를 활용하기 위해서는 병렬화 문제를 해결해야한다.
2000년대에는 프로세서가 전력 장벽에 부딪힌다.
회로를 이루는 물질의 녹는점 이상으로 온도가 올라가는 것을 방지하면서
회로를 소형화 고성능화하기가 어려워진다.
사람들은 이러한 문제를 멀티코어 프로세서를 통해 해결해왔다.
- 마이크로프로세서와 마이크로 컴퓨터
메모리와 I/O가 프로세서코어(CPU)와 같은 패키지에 들어있지 않으면 마이크로프로세서라 부른다.
보통 큰 시스템에 들어가는 부품으로 쓰인다.
모든 요소를 한 칩에 패키징하면 마이크로컴퓨터라고 부른다.
아두이노는 하버드 구조의 컴퓨터다.
ㅁ 프로시저, 서브루틴, 함수
중복된 코드를 줄이면 코드가 메모리를 덜 차지하고,
코드에 버그가 있는 경우 한 군데만 고치면 된다는 장점이 있다.
함수(또는 프로시저, 서브루틴)는 코드를 재사용하는 주요 수단이다.
프로그램 실행중에 함수를 실행하기 위해서는 많은 작업이 필요하다.
함수를 실행하려면 반환주소를 계산해야하고,
함수를 호출하는 코드가 차지하는 주소도 감안해야한다.
대부분의 기계는 이런 과정을 돕는 명령어를 제공하는데,
ARM 프로세서에는 링크 레지스터를 사용한 분기 명령어를 제공한다.
함수로 호출하는 명령어와 현재 명령어 다음 위치를 저장하는 명령어를 하나로 합친 것이다.
ㅁ 스택
함수가 다른 함수를 호출하거나 함수가 자기 자신을 호출하는 경우가 자주 있다.
이런 경우 필요한 것은 접시더미 같은 역할을 할 수 있는 장치이다.
함수를 호출할 때는 반환주소를 접시더미 맨 위에 넣고(푸쉬),
함수 호출에서 돌아올 때는 접시 더미 맨 위의 접시를 보고 반환주소를 결정한 후, 해당 접시를 제거(팝)한다.
이런 구조를 물건을 쌓아올린다는 뜻의 스택, 혹은 LIFO 구조라 부른다.
스택에 물건을 푸시하는데 더 이상 들어갈 공간이 없으면 스택 오버플로라 하고,
빈 스택에서 물건을 가져오려고 하는 경우는 스택 언더플로라고 부른다.
대부분의 컴퓨터 하드웨어는 스택을 지원하며
스택 오버플로를 항상 검사하지 않아도 되는 한계 레지스터도 지원한다.
ㅁ 인터럽트
순서도에서 어떤 작업을 더 작은 하위작업으로 나누고,
각 하위 작업 사이의 문을 검사하는 과정이 포함될 수 있다.
이러한 과정이 늘어나면 문을 검사하는데 시간을 많이 소비하게 된다.
실행 중인 프로그램을 잠깐 중단(인터럽트)시켜 주의를 기울여야하는 외부의 요소에 대응 할 수 있다면
이런 비효율 문제를 효율적으로 개선할 수 있다.
인터럽트 시스템은 적절한 신호가 들어오면 CPU 실행을 잠깐 중단시키르 수 있는 핀이나 전기 연결을 포함한다.
CPU 주변장치에서 인터럽트 요청을 생성하면, CPU는 현재 실행 중인 명령어까지 실행 한 뒤,
실행 중인 프로그램을 잠시 중단하고 인터럽트 핸들러라는 함수를 실행한다.
인터럽트 핸들러 작업을 마치고 나면 실행 중이던 프로그램이 중단되었던 위치부터 다시 실행을 계속한다.
인터럽트에서 고려해야할 요소는
1. 인터럽트에 대한 응답시간
2. 원래대로 돌아가기 위한 현재상태 저장 방법이다.
운영체제는 물리적 인터럽트 외에도
시그널 메커니즘이나 이벤트라고 불리는
가상 인터럽트나 소프트웨어 인터럽트 시스템을 제공하기도 한다.
ㅁ 상대 주소 지정
여러 프로그램을 동시에 실행하려면 각 프로그램을 서로 전환시켜줄 수 있는 관리자 프로그램이 필요하다.
이를 커널이라고 부른다.
사용자 프로그램의 실행시간을 조절하는 스케줄링 기법을 시분할이라고 한다.
이런 방법은 안정적이지만 느리다.
각 프로그램에서 각기 다른 공간을 허용할 수 있으면 훨씬 더 빠르게 시분할 실행이 가능하다.
절대 주소 지정은 명령어 주소가 특정 메모리 주소를 가리킨다.
절대 주소 지정으로 프로그램을 실행하면,
1000번지에서 실행되도록 만들어진 프로그램을 2000번지에서 읽어들이면 제대로 실행되지 않는다.
어떤 컴퓨터들은 인덱스 레지스터를 추가해 해결한다.
인덱스 레지스터는 명령어에 들어있는 주소에 인덱스 레지스터 값을 더해 유효주소를 계산한다.
상대 주소 지정은 주소를 명령어 기준으로 상대적으로 해석 한다.
프로그램을 실행 할 때, 필요한 메모리 주소를 원하는 메모리의 위치로 자유롭게 재배치 할 수 있다.
ㅁ 메모리 관리 장치 MMU
멀티태스킹은 필수품으로 변해왔다.
프로그램에 버그가 있다거나, 사용자 프로그램1의 메모리를 사용자 프로그램2가 덮어쓴다거나,
OS의 메모리를 덮어쓰는 경우는 인덱스 레지스터와 상대 주소지정은 멀티태스킹에 도움이 될 수 있지만 충분하지 않다.
이를 해결하기 위해 오늘날 대부분의 마이크로프로세서에는 MMU가 포함된다.
MMU는 가상주소와 물리주소를 구분한다.
가상주소범위는 물리적 메모리 주소보다 큰 경우가 많다.
페이지 테이블이라는 RAM 영역을 통해 주소를 변환한다.
프로그램 입장에서 가상메모리가 연속적인 것으로 보이지만,
실제 물리 메모리상 위치는 굳이 연속적일 필요는 없다.
가상 메모리 중 일부가 같은 물리 메모리를 함께 사용하는 공유메모리 기능을 제공할 수 있다.
프로그램이 물리적 메모리에 연관되지 않은 주소에 접근하면 페이지 폴트 예외가 발생한다.
MMU가 추가 메모리를 할당하게 해서 스택공간을 늘리고 프로그램 실행을 계속할 수 있다.
MMU로 인해 폰노이만 구조와 하버드 구조의 구분이 의미 없어졌다.
ㅁ 가상 메모리
운영 체제는 희소한 하드웨어 자원을 사용하려 경합하는 프로그램들 사이에서 자원 분배를 관리한다.
MMU가 프로그램의 가상주소를 물리메모리 부소로 변환해준다.
가상 메모리는 페이징 폴트 메커니즘을 활용하여 실제 물리 메모리 이상의 많은 메모리를 사용할 수 있다.
요청 받은 메모리가 사용 가능한 물리적 메모리 크기보다 크면,
OS는 필요하지 않은 메모리 페이지를 더 느리지만 용랑이 큰 디스크로 옮긴다(스왑아웃)
스왑아웃한 페이지에 프로그램이 접근하면 운영체제는 필요한 메모리 공간을 확보하고
요청받은 페이지를 다시 메모리로 불러들인다(스왑인)
이런 식으로 페이지를 처리하는것을 요구불 페이징demand paging이라 한다.
스와핑이 일어나면 시스템 성능이 크게 저하된다.
가상 메모리 시스템은 성능 저하를 막기 위해 최소 최근 사용LRU 알고리즘 등 다양한 기법을 활용한다.
ㅁ 시스템 공간과 사용자 공간
CPU에는 컴퓨터가 시스템 모드에 있는지 사용제 모드에 있는지 결정하는 비트가
어떤 레지스터 안에 들어 있다.
사용자 프로그램으로부터 운영체제를 보호하고,
사용자프로그램을 다른 사용자 프로그램으로부터 보호한다.
ㅁ 메모리 계층과 성능
빠른 CPU가 느린 메모리를 기다리느라고 아무 일도 하지 않는 경우를 줄이기 위해 많은 방법을 사용한다.
주 메모리는 프로세서보다 1/10 밖에 속도가 나지 않는다.
캐시라는 하드웨어는 메모리보단 작지만 훨씬 빠르고 프로세서와 같은 속도로 작동한다.
메모리에서 연속된 열에 있는 데이터를 한꺼번에 가져온다. 메모리에 접근하는 패턴이 순차적이 아니어서
캐시실패가 일어나면 결국에는 메모리에 있는 데이터를 읽어야 한다.
캐시 메모리에도 계층에 있다. CPU에서 멀어질수록 캐시는 더 느려지고 커진다.
이를 L1, L2, L3 캐시라고 부른다.
캐시를 활용하기 위한 디스패처, 분기ㅖ층 회로, 순서를 벗어나는 실행을 처리하는 회로 등이 있다.
ㅁ 코프로세서
프로세서에서 몇 가지 연산을 위한 더 단순화한 장치가 코프로세서 이다.
ㅁ 메모리상의 데이터 배치
메모리는 명령어만 담는게 아니라 데이터도 담는다.
동적 데이터는 프로그램을 실행하기 전에는 크기를 알수 없는 데이터이다.
동적 데이터는 정적데이터 위에 쌓이며, 힙이라 부른다.
스택은 최상위에 위치하여 아래로 자라난다.
MMU가 없는 경우, 스택 - 힙 - 정적데이터 - 명령어의 순서로 메모리상 데이터가 배치된다.
ㅁ 프로그램 실행
프로글매을 여러 조각으로 나누면 이 모든 조각을 하나로 엮거나 연결(링크)할 방법이 필요하다.
링커라는 프로그램은 여러 프로그램 조각을 하나로 연결해 실행한다.
과거에 라이브러리 파일과 프로그램을 직접 연결해 실행파일을 만드는 정적 링크를 사용하였다.
동적 링크는 여러 프로그램이 같은 라이브러리를 공유하여 메모리 낭비를 줄일 수 있다.
ㅁ 메모리 전력 소비
데이터를 메모리에서 이리저리 옮기면 전력이 소비된다.
전력 소비와 성능 사이의 균형을 잡는 일은 어렵지만,
코드를 작성할 때도 이를 염두에 두어야한다.
'Book > 프로그래밍일반' 카테고리의 다른 글
| [프로그래밍 일반] 한 권으로 읽는 컴퓨터 구조와 프로그래밍_ch7 데이터 구조와 처리 (0) | 2024.05.20 |
|---|---|
| [프로그래밍 일반] 한 권으로 읽는 컴퓨터 구조와 프로그래밍_ch6 입출력과 네트워킹 (0) | 2024.05.13 |
| [프로그래밍 일반] 한 권으로 읽는 컴퓨터 구조와 프로그래밍_ch4 컴퓨터 내부 구조 (0) | 2024.04.29 |
| [프로그래밍 일반] 한 권으로 읽는 컴퓨터 구조와 프로그래밍_ch3 메모리와 디스크의 핵심 : 순차 논리 (0) | 2024.04.15 |
| [프로그래밍 일반] 한 권으로 읽는 컴퓨터 구조와 프로그래밍_ch2 전자 회로의 조합 논리 (0) | 2024.04.08 |