프로세서의 기본 부품과 개념

Jin Hur·2021년 8월 17일
0

reference: "프로그래머가 몰랐던 멀티코어 CPU 이야기" / 김민장, "Computer System A Programmers'Perspective" / 랜달 E.브라이언트

마이크로아키텍처

마이크로프로세서 하나를 만드는데 필요한 알고리즘 및 회로 수준의 구조를 정의하는 것을 마이크로아키텍처라고 부름.
대표적인 마이크로아키텍처로는 "인텔 펜티엄 프로의 P6 구조". P6 구조는 펜티엄 4를 제외한 거의 대부분의 인텔 프로세서 마이크로아키텍처의 근간이다.

마이크로프로세서 설계

  1. 마이크로아키텍처 설계
    목표한 성능을 가능케 하는 여러 알고리즘과 테크닉 개발.
    예를 들어 새로운 캐시 알고리즘을 시뮬레이터에서 검증하고, 이 정제된 마이크로아키텍처의 알고리즘은 RTL이라는 언어로 기술됨. C/C++ 같은 고급 언어로 기술된 알고리즘을 실제 하드웨어 설계 언어로 변환한 것.

  2. 마이크로아키텍처 디자인이 끝나면 이제 로직 디자인으로 넘어감. 앞서 얻은 RTL을 실제 하드웨어 구현에 적합한지 테스트하고 가다듬어 최종적으로 HDL언어로 바꾼다. 대표적으로 베릴로그 같은 언어가 쓰임.


프로세서 구성

source: https://kblab.tistory.com/315

산술 논리 장치: 프로세서 속 계산기

덧셈 및 각종 논리 연산이 이루어지는 디지털 회로.
ALU가 지원하는 연산은 보통 프로세서가 명령어로 바로 지원한다. x86 ISA는 add, sub, imul, idiv 같은 정수 사칙 연산이 있으며, 비트 논리 연산 and, or, xor도 제공. 참고로 불리언 연산은 별도의 명령어가 아닌 분기문의 조합으로 구현.

ALU 인터페이스 표현
void ALU(int function, int operandA, int operandB, int* result, int* flags);
// A, B: 피연산자
// F: 수행하고자 하는 연산 종류
// R: 연산 결과
// D: 연산의 부가 결과

부가 결과: 계산 결과의 상태 값들. 예를 들어 연산 결과의 오버플로우 여부, 결과 값이 0과 같은지, 혹은 패리티 값을 별도로 저장할 수 있음.
대표적으로 x86의 EFLAGS(32bit), RFLAGS(64bit) 레지스터가 이에 해당.

연산 종류와 회로 분리

보통 프로세서는 처리 시간에 따라 단순한 정수 연산, 복잡한 정수 연산 그리고 부동소수점 계산기로 분리 처리. 수많은 프로그램의 행동을 분석한 결과, 연산의 종류에 따라 회로를 분리하여 사용하는 것이 성능상 더 이득이기에.

다른 종류의 계산

정수와 부동소수점 처리는 모두 일반 연산자, 즉 스칼라 타입을 취하는 형태.
공간 좌표를 표현하거나 물체의 움직임을 기술할 때는 벡터를 자주 이용. 이런 벡터로 표현된 데이터는 과학이나 멀티미디어 프로그램에서 매우 많이 접할 수 있으므로 이 부분을 특별히 처리해 성능을 높이는 것은 make common case fast 원리와도 맞아떨어짐. 이런 연산은 바로 그래픽 연산 장치인 GPU와 벡터 연산에서 흔히 찾아볼 수 있음.


클록, 1사이클이 가지는 의미

디지털 회로에서 클로은 바로 오케스트라의 지휘자.
프로세서가 처리하는 명령 하나는 여러 마디로 구분. 이런 마디를 디지털 회로에서는 상태(state)라고 부름. (디지털 회로는 다른 말로 유한 상태 기계라 함)
기계 명령어 하나를 처리하려면 시작 상태에서 출발하여 여러 중간 상태들을 지나 마지막 상태로 도달해야 명령 하나가 완료됨. 명령어 하나가 연주할 내용이라면 클록은 지휘자와 같다. 지휘자의 박자에 맞춰 다음 마디로 넘어가듯 디지털 회로는 다음 상태로 가려면 반드시 클록 신호가 있어야 함.
2GHz의 프로세서는 1초에 20억번(1G: 약 10억)의 클록 신호를 발생시킨다. 프로세서 내부 상태가 1초에 20억번 변할 수 있음을 의미.


메모리 계층

컴퓨터 연산 결과는 궁극적으로 메모리 상태의 변화로 볼 수 있음. 모니터에 그려지는 그래픽 화면도 결국 픽셀 값을 저장하는 메모리(프레임 버퍼) 상태 변화를 의미하고, 대량의 연산 결과를 파일에 쓰는 것도 결국 메모리 내용을 저장 장치로 옮기는 것.

폰 노이만 구조에서 메모리는 컴퓨터에서 너무나 중요한 역할을 하며, 실제로도 메모리 대역폭(bandwidth)와 레이턴시(latency)를 얼마나 개선하는가가 컴퓨터 시스템의 성능 향상에 매우 큰 영향을 끼침.

메모리 계층의 맨 꼭대기, 가장 빠르면서 가장 값이 비싼 메모리는 레지스터다. 이미 기계어 코드에서 eax, rax, r5와 같은 이름으로 많이 보임. 레지스터는 앞서 얘기한 컴퓨터 구조적 상태 중 일부로 프로그래머는 프로그램 실행 도중 레지스터 상태 관찰 가능.

컴퓨터 구조적 상태(architectural state): 외부에서 보이는 현재 프로세서 상태를 컴퓨터 구조적 상태라함. 구체적으로 말하면 현재 프로세서가 수행 중인 프로세스의 상태를 지닌 각종 레지스트의 값들임. (하드웨어 스레드 혹은 논리 프로세서마다 구조적 상태를 가짐.)

레지스터 종류

  • 범용 목적 레지스터: 피연산자 변수를 메모리에서 읽어 저장하는 공간, 또한 연산 결과도 저장한다. 이 공간의 값을 최종적으로 메모리에 쓴다.
  • 프로그램 카운터(PC): 프로세서의 상태를 관리하는 변수들을 기억. PC 레지스터는 현재 수행중인 명령어 주소를 갖고 있음. x86에서는 IP(Instruction Pointer)라는 이름으로 불림. 32비트에선 EIP, 64비트에선 RIP
  • 컨트롤 레지스터(CR): 시스템 내부 상태를 관리하는 레지스터. x86에서는 CR 레지스터가 시스템의 여러 상태를 기억. CR0과 CR4는 컨트롤 상태를 갖고 있고, CR3의 경우 현재 수행 중인 프로세스의 페이지 테이블(가상 메모리 변환을 위한 자료구조)를 가리킴.

=> 위 레지스터들의 종류는 외부에 노출된, 즉 프로그래머가 볼 수 있는 레지스터들임. 이러한 레지스터들을 보통 구조 레지스터(architectural register) 혹은 논리 레지스터(logical register)이라 부름. 실제 내부 구현은 이와 독립적으로 훨씬 많은 레지스터로 작동. 외부 인터페이스만 ISA가 정의하는 대로 맞추면 되고 내부 구현은 더 자유롭게 함. 프로세서 내부에서 쓰이는, 즉 외부로 노출되지 않는 레지스터를 물리 레지스터라고 한다. 구조적 레지스터와 물리 레지스터 사이를 관리하는 알고리즘과 테이블이 필요할 것. 이 레지스터와 관련된 내용은 비순차 실행과 관련.

레지스터 파일

프로세서는 이 레지스터를 레지스터 파일이라는 장치로 구현.

레지스터 대체 최적화

컴파일러는 최대한 레지스터를 효율적으로 쓰도록 최적화함. 레지스터에 여유가 있다면 불필요한 변수를 실제 메모리에 할당하지 않고 레지스터로 대체하는 최적화는 컴파일러의 기본적 의무.


컨트롤 장치(CU)

ALU나 레지스터 파일은 "Datapath"로 구분하며, 명령어를 메모리에서 읽어와서 해독하고 이것을 적절한 ALU에 넣어 값을 얻게 하는 등의 제어를 담당하는 것이 컨트롤 유닛(CU)임.
이 컨트롤 장치는 당연히 마이크로아키텍처에 큰 영향을 받음. 예를 들어 파이프라인과 비순차 실행은 모두 이 컨트롤 장치에 해당.


정리

프로세서는 크게 데이터패스(ALU, 레지스터들)와 컨트롤 장치로 나뉨. 데이터패스는 실제 계산을 담담하는 산술 논리 연산 장치(ALU)와 메모리 계층의 여러 요소(레지스터 파일, 캐시, 메모리 장치)가 있음. 컨트롤 장치는 이 데이터패스를 서로 조율하여 명령어가 오가면서 계산이 이루어지도록 제어.

0개의 댓글