cpu에 관하여

June 24, 2024 (3mo ago)

CPU의 구성 요소

cpu의 구성요소

cpu는 위의 그림에서 볼 수 있듯이 제어 장치, 연산 장치(ALU), 레지스터로 구성이 되어 있습니다. 이 구성 부품들이 각각 무슨 역할을 수행하는지에 대해서 자세하게 알아 보겠습니다. 부품들에 대해서 자세하게 다루기 이전에 기본적으로 컴퓨터의 장치들은 cpu가 명령을 내리기 이전에는 작동하지 않습니다. 그렇기 때문에 cpu에서 무엇보다 중요한 역할이라고 말할 수 있는 것이죠 이러한 cpu의 부품들 중 가장 먼저 다룰 것은 ALU 연산처리 장치입니다.

1. ALU, 연산처리 장치

연산처리 장치는 제어장치로부터 제어신호를 입력 받습니다. 그리고 이 후 입력 받은 제어를 처리하기 위하여 필요한 레지스터에 저장되어 있는 피연산자들을 불러오고 해당 피연산자들을 연산한 결과를 잠시 다른 결과를 저장할 수 있는 레지스터에 저장합니다.

이때 바로 메모리에 저장하지 않고 레지스터에 잠시 저장해놓는다는 이유가 무엇일까요? 이유는 성능 때문입니다. CPU에 성능에서 중요한 요소 중 하나는 메모리에 얼마나 덜 접근하는지가 성능에 많은 영향을 미칩니다. 이는 cpu가 데이터를 읽는데 걸리는 시간이 레지스터가 월등히 더 빠르기 때문입니다.

만약 연산처리에 관한 결과를 불러오거나 사용해야 할 일이 있을 경우 목적 레지스터에 값을 저장하고 해당 값이 더 이상 유용하지 않거나 해당 결과를 계속해서 이용해야 할 필요성이 있는 경우 메모리에 추가하거나 제거하여 결과값을 목적 레지스터에서 제거합니다.

이 후 해당 결과 값에 대해서 필요한 추가 정보가 있을 경우 해당 정보를 플래그 레지스터에 추가로 표기합니다. 플래그 레지스터에 포합되는 정보 또한 중요한 역할을 합니다. 플래그 레지스터에 어떠한 정보가 담기는지 알아보겠습니다.

  • 부호 플래그 연산한 결과의 부호를 나타내는 플래그입니다.

  • 제로 플래그 연산 결과 값이 0인지 0이 아닌지를 나타내는 플래그입니다.

  • 캐리 플래그 연산 결과에서 올림 수나 내림 수가 발생했는지를 나타내는 플래그입니다.

  • 오버플로우 플래그 오버플로우, 연산에 할당된 비트 수로 표현할 수 있는 최대값이나 최소값을 초과하는 상황을 표기하는 플래그 입니다.

  • 인터럽트 플래그 인터럽트가 발생했는지에 관한 여부를 나타내는 플래그입니다.

  • 슈퍼 바이저 플래그 커널 모드가 실행 중인지 사용자 모드로 실행 중인지를 구분할 수 있는지 나타내는 플래그입니다.

이 플래그는 다른 장치에서도 참조하고 사용하는 플래그이기 때문에 연산장치에서만 사용되는 것이 아니기 때문에 어떤 것들을 나타내는 구나 정도는 기억 해놓으시면 다시 이 플래그가 나타났을 경우 당황하지 않을 수 있겠죠?

2. 제어 장치

제어 장치는 컴퓨터에서 이루어지는 모든 작업을 어떻게 수행할 것인지를 다루는 중요한 역할을 합니다.하지만 이러한 제어 장치는 단순히 제어 신호를 내보내는 것만이 아니라 받아들이는 정보 또한 존재합니다. 이에 대해서, 제어 신호가 받아들이는 정보에 대해서 다루어 보겠습니다.

클럭 신호를 받아들입니다. 클럭은 컴퓨터의 모든 부품을 일사분란하게 움직일 수 있게 하는 시간의 단위를 뜻합니다. 하지만 컴퓨터의 모든 부품이 클럭 신호에 맞춰서 작동하는 것은 아니고 단지 박자에 맞춰서 작동하는 것이지 부품들이 이 박자마다 한 번씩 작동을 하는것은 아닙니다.

제어장치는 해석해야할 명령어와 플래그 레지스터 속의 플래그 값을 받아들입니다. 또한 시스템 버스 중 제어 버스로 부터 전달된 신호를 받아들입니다. 이러한 신호들을 받아들이고 받아들인 정보들을 토대로 어떠한 명령을 내릴 것인지를 파악해서 제어 신호를 전송합니다. 예를들어 레지스터에서 어떤 레지스터로 데이터를 이동 시킬 것인지 아니면 연산장치에서 어떤 연산을 할 것인지에 관한 지시를 전송하는 역할을 하는 것이 제어 장치입니다.

3. 레지스터

레지스터의 역할은 무엇일까요? 레지스터는 cpu가 실행하기 위한 정보들을 주로 담고 있는 역할을 수행합니다. 이러한 기능은 메모리에 대해서 알고 계시다면 중복된다고 생각할 수도 있을 것 같습니다. 하지만 이 둘은 굉~장히 큰 차이가 있습니다! 우선 가장 큰 차이인 속도에 대해서 이야기 해보겠습니다.

레지스터가 메모리보다 훨씬 빠른 속도를 지니고 있습니다. 이러한 이유는 무엇일까요? 단순히 생각해볼 수 있는 이유로 우선 물리적인 거리가 가깝다는 특징이 있습니다. 레지스터는 cpu 내부에 존재하기 때문에 메모리보다 cpu에 더 가까운 위치에 더 빠른 속도로 접근이 가능합니다. 또한 이런 특징으로 인해서 메모리의 경우 데이터를 읽어오기 위해서는 시스템 버스를 이용해야 하지만 레지스터는 시스템 버스를 이용하지 않아도 됩니다. 또한 용량의 차이가 있습니다. 우리가 흔히 사용하는 메모리를 생각해보면 제일 작은 메모리의 용량은 8GB인 반면 레지스터는 대략 128바이트 정도의 크기에 해당하기 때문에 속도에서 엄청난 차이가 있을 수 밖에 없습니다.

레지스터의 종류는 다양합니다. 그 중에서 반드시 알아야 할 레지스터는 아래와 같습니다.

  1. 프로그램 카운터
  2. 명령어 레지스터
  3. 메모리 주소 레지스터
  4. 메모리 버퍼 레지스터
  5. 플래그 레지스터
  6. 범용 레지스터
  7. 스택 포인터
  8. 베이스 레지스터

위의 레지스터들이 어떤 역할을 수행하는지에 대한 것을 중심으로 이해하고 있으면 충분합니다. 위에서부터 하나 하나 다루어 보겠습니다.

프로그램 카운터의 경우 다음에 실행할 메모리의 주소를 저장하는 용도로 사용이 됩니다. 그렇다면 다음에 실행할 메모리의 기준은 뭘까요? 이는 PC에서 사용자가 실행하는 프로그램에 따라서 해당 프로그램의 데이터를 저장하고 있는 메모리의 주소를 참조하여 저장하는 것입니다. 즉, 프로그램 카운터에 저장될 주소의 기준은 PC에 실행된 프로그램을 기준으로 저장이 됩니다.

범용 레지스터는 이름 그대로 범용, 다양하고 일반적인 상황에서 사용할 수 있는 레지스터 입니다. 메모리 주소 레지스터는 주소 버스로 부터 주고 받을 값 만을 저장하고 메모리 버퍼 레지스터의 경우 데이터 버스로 부터 주고 받을 값만 저장하지만 범용 레지스터는 버스를 구분하지 않고 데이터를 저장할 수 있다는 특징을 지닙니다. 플래그 레지스터의 경우 연산 결과가 부가적인 정보를 저장하여 사용합니다.

메모리 주소 레지스터는 주소 버스로 신호를 전달할 메모리에 대한 주소를 저장합니다. 메모리 버퍼레지스터는 데이터 버스로 부터 전달 받은 데이터를 저장하는 역할을 수행하는 레지스터입니다. 이후는 그림을 통해서 더 자세하게 설명하겠습니다.

레지스터 주소 지정 방식

우선 프로그램 카운터가 증가합니다. 프로그램 카운터에 저장된 101 번지의 주소를 읽어 오기 위해서는 주소 버스로 어떤 주소를 불러 올 것인지를 내보낼 수 있어야 합니다. 이를 위해서 프로그램 카운터에 저장되어 있는 주소를 메모리 주소 레지스터로 전달하여 저장을 시킵니다.

그럼 메모 주소 레지스터는 메모리 읽기를 수행하기 위하여 레지스터에 저장되어 있는 주소를 주소 버스로 전달합니다. 이와 동시에 제어 장치는 제어 버스로 부터 해당 주소에 있는 메모리를 읽어 올 수 있게끔 제어 신호를 전달합니다.

그럼 메모리는 데이터 버스로 부터 CPU가 메모리 데이터를 읽어 올 수 있게끔 주소에 저장되어 있는 데이터를 데이터 버스에 전달하고 해당 데이터를 메모리 버퍼 레지스터에 저장을 합니다. 이후 메모리 버퍼 레지스터는 명령어 레지스터에 전달하고 명령어 레지스터는 해당 데이터를 해석하여 제어 신호를 발생시킵니다.

앞선 설명에서 주소 버스, 데이터 버스, 제어 버스들이 계속해서 등장한 것을 보실 수 있습니다. 이러한 버스가 무엇이고 왜 이용을 하는 것인지에 대해서 설명하겠습니다. 메모리는 자체적으로 어떤 기능을 수행할 수 있는 기능을 소유하고 있지 않습니다. 그렇기 때문에 다른 부품들과 통신하기 위해서 버스는 컴퓨터 시스템의 각 구성 요소가 효율적으로 통신하고 작동할 수 있게끔 도와주는 역할을 수행하여 작업을 수행할 수 있게끔 하는 매우 매우 중요한 부품입니다.

여기서 추가적으로 알아야할 것은 버스는 공동 자원에 포함된다는 것입니다. CPU에서 이루어지는 모든 작업은 공동 자원을 사용합니다. 이러한 공동자원들은 동시에 이용할 수 있습니다. 예를 들어 제어신호를 제어 버스에 전달하는 동시에 데이터 버스를 이용하여 데이터를 읽어올 수 있다는 이야기 입니다. 하지만 이러한 동시 작업이 너무 많이 일어날 경우 메모리 부족과 스케줄링 오버헤드등의 문제가 발생할 수 있습니다. 그렇기 때문에 우리는 이러한 작업을 최적화 시킬 필요가 있습니다. 이에 대해서는 다음 단에서 자세하게 다루어 보겠습니다.

주소 지정 방식

앞서 설명헀던 글에서 계속해서 등장했던 것이 있습니다! 바로 주소를 저장합니다 입니다. 그렇다면 주소를 어떻게 저장하는지 알아보지 않을 수 없겠죠?

1. 스택 주소 지정 방식

스택은 프로그래밍 공부를 했으면 적어도 한 번씩은 꼭 듣게 되는 용어죠? 스택이 어떠한 자료구조 인지에 대해서는 ~에서 다루었으니 넘어가겠습니다. 메모리에서 스택은 특정 영역을 스택 영역이라고 지정하여 이용합니다. 예를 들어 1000 ~ 1050까지는 스택 영역이라고 암묵적인 합의를 하여 스택 처럼 사용합니다. 스택 주소 지정 방식은 스택 포인터를 이용하여 주소를 추적합니다. 데이터가 들어올 경우 위치가 갱신되고 빠져나갈 경우 갱신되는 방식을 이용하여 마지막으로 사용된 주소를 가르키고 있는 스택포인터를 활용하여 주소를 지정하는 방식을 스택 주소 지정 방식이라고 합니다.

2. 변위 주소 지정 방식

변위 주소 지정 방식은 명령어를 이용하여 다음에 사용할 주소를 지정하는 방식입니다. 앞서 ~에서 명령어의 구조에 대해서 섦명했습니다. 명령어에는 메모리의 주소가 담길 때도 있습니다. 바로 지금 이죠! 원래 명령어는 연산 코드 + 오퍼랜드 였지만 지금은 연산 코드 + 레지스터 필드 + 오퍼 랜드로 구성이 되어 사용이 됩니다. 변위는 처음 위치에서 특정 값을 더하거나 빼는 것으로 인하여 생기는 위치 변화를 이야기 합니다. 그럼 여기서 변위의 기준점은 무엇일까요? 이 경우 변위의 기준점은 오퍼 랜드입니다. 그럼 더해지거나 빼지는 값이 저장되는 곳은 어디일까요? 레지스터 필드입니다! 이러한 지식을 바탕으로 변위 주소의 종류에 대해서 다루어 보겠습니다.

** 1. 상대 주소 지정 방식 **

상대 주소 지정 방식은 레지스터 필드에 프로그램 카운터의 값을 저장합니다. 그리고 오퍼랜드에 있는 값과 더하여 나온 결과를 주소로 이용하여 주소를 지정합니다. 프로그램 카운터에 저장된 값이 1000이고 오퍼랜드에 저장된 값이 -3 일 경우 현재 주소에서 3개 이전의 위치에 있는 주소를 다음 주소로 지정합니다. +3일 경우는 앞에 위치한 주소를 지정하겠죠?

** 2. 베이스 주소 지정 방식 **

베이스 주소 지정 방식은 베이스 레지스터를 활용하여 주소를 지정합니다. 베이스 레지스터는 메모리의 특정 영역(예: 프로그램 코드, 데이터 영역 등)의 시작 주소를 저장하는 특수 목적 레지스터입니다. 이 방식에서는 베이스 레지스터에 저장된 기준 주소에 오프셋을 더하여 실제 메모리 주소를 계산합니다. 즉, 실제 주소는 베이스 레지스터 값에 오프셋, 오퍼랜드에 저장되어 있는 값을 더한 값이 실제 주소가 됩니다. 이러한 방법은 메모리를 보호하는데 효과적인 기능을 수행합니다. 왜 그럴까요? 처음 시작할 때 해당 프로그램에 대한 기준점을 기준으로 오프셋을 추가하면서 이동함으로 프로그램이 할당 받은 영역을 벗어나지 않게 됩니다. 그렇기 때문에 프로그램 간의 간섭이 일어나지 않는 효과적인 주소 지정 방식입니다!

마무리

지금까지 컴퓨터의 부품들 그 중에서도 특히 CPU에 대해서 자세하게 알아봤습니다. CPU는 컴퓨터의 핵심, 두뇌입니다! 그렇기 떄문에 어떤 부품들이 있고 어떤 역할을 수행하는지에 대해서 알아두는 것은 굉~장히 중요합니다. 물론 재가 다룬 내용도 대략적인 설명에 불과합니다. 이 다음으로 다룰 것은 CPU의 성능 향상 기법에 대해서 다루어 보겠습니다.