프로세서에 32 개의 레지스터가있는 이유는 무엇입니까?


52

나는 왜 프로세서가 32 개의 레지스터에서 멈추었는지 궁금했다. 지금까지 가장 빠른 머신입니다. 더 많은 레지스터로 더 큰 프로세서를 만드는 것이 어떻습니까? RAM에 덜가는 것을 의미하지 않습니까?


2
특정 지점 이상으로 모든 로컬 변수가 레지스터에 맞는 것 같습니다. 당신이 작업하고있는 실제 데이터는 아마도 너무 클 것입니다
Niklas B.

14
반품 감소. 분명히 레지스터는 RAM보다 "다양한 의미에서"더 비싸거나 8GB의 레지스터 만 가질 것입니다.
David Richerby

5
너무 빠른 이유 중 하나는 많은 것이 없기 때문입니다.
stackErr

5
CPU의 총 레지스터 수와 한 번에 사용할 수있는 레지스터 수에는 차이가 있습니다.
Thorbjørn Ravn Andersen

CPU와 GPU는 각각 캐시와 멀티 스레딩을 통해 대기 시간을 숨 깁니다. 따라서 CPU에는 레지스터가 거의 없지만 GPU에는 레지스터에 수만 개가 있습니다. 이러한 모든 장단점과 요소에 대해 설명하는 GPU 레지스터 파일에 대한 설문지를 참조하십시오 .
user984260

답변:


82

첫째, 모든 프로세서 아키텍처가 32 개의 레지스터에서 중지 된 것은 아닙니다. 명령어 세트에 32 개의 레지스터가 노출 된 거의 모든 RISC 아키텍처에는 실제로 32 개의 정수 레지스터와 32 개의 부동 소수점 레지스터가 있습니다 (따라서 64). 부동 소수점 "add"는 정수 "add"와 다른 레지스터를 사용합니다. SPARC 아키텍처에는 레지스터 창이 있습니다.. SPARC에서는 한 번에 32 개의 정수 레지스터에만 액세스 할 수 있지만 레지스터는 스택처럼 작동하며 한 번에 16 개의 새 레지스터를 푸시 및 팝할 수 있습니다. HP / Intel의 Itanium 아키텍처는 128 개의 정수 및 128 개의 부동 소수점 레지스터가 명령어 세트에 노출되었습니다. NVidia, AMD, Intel, ARM 및 Imagination Technologies의 최신 GPU는 모두 레지스터 파일에 대량의 레지스터를 노출합니다. (이것이 NVidia 및 Intel 아키텍처에서 사실이라는 것을 알고 있습니다 .AMD, ARM 및 Imagination 명령어 세트에는 익숙하지 않지만 레지스터 파일도 크다고 생각합니다.)

둘째, 대부분의 최신 마이크로 프로세서는 리소스를 재사용해야하는 불필요한 직렬화를 제거하기 위해 레지스터 이름 변경 을 구현 하므로 기본 물리적 레지스터 파일이 더 클 수 있습니다 (일부 컴퓨터에서는 96, 128 또는 192 개의 레지스터). 컴파일러가 너무 많은 고유 레지스터 이름을 생성하는 동시에 스케줄러에 더 큰 레지스터 파일을 제공해야합니다.

명령어 세트에 노출 된 레지스터 수를 추가로 늘리기가 어려운 두 가지 이유가 있습니다. 먼저, 각 명령어에서 레지스터 식별자를 지정할 수 있어야합니다. 32 개의 레지스터에는 5 비트 레지스터 지정자가 필요하므로 3- 주소 명령어 (RISC 아키텍처에서 공통)는 레지스터를 지정하기 위해 32 개의 명령어 비트 중 15 개를 소비합니다. 이를 6 또는 7 비트로 늘리면 opcode 및 상수를 지정할 공간이 줄어 듭니다. GPU와 Itanium은 훨씬 더 큰 명령어를 가지고 있습니다 . 더 큰 명령어는 비용이 듭니다 : 더 많은 명령어 메모리를 사용해야하므로 명령어 캐시 동작이 덜 이상적입니다.

두 번째 이유는 액세스 시간입니다. 메모리가 클수록 데이터에 액세스하는 속도가 느려집니다. (기본 물리학의 관점에서 : 데이터는 2 차원 공간에 저장되므로 비트를 저장하는 경우 특정 비트까지의 평균 거리는 입니다. 레지스터 파일은 작은 다중 포트 메모리 및이를 더 크게 만드는 데 따른 제약 중 하나는 결국 더 큰 레지스터 파일을 수용하기 위해 시스템의 클럭을 느리게 시작해야한다는 것입니다. 일반적으로 총 성능 측면에서 이는 손실입니다. nO(n)


1
SPARC64 VIIIfx의 256 FPR과 32 개의 추가 비 창문 GPR에 대해 언급했을 것입니다. 다음 1 개 또는 2 개의 명령어에 대해 각각 13 비트를 제공하는 Set XAR 명령어를 추가하여 달성했습니다. HPC를 대상으로하므로 레지스터 수를보다 잘 이해할 수 있습니다. 또한 더 많은 레지스터와 관련된 트레이드 오프와 기술에 대해 설명하고 싶었습니다. 그러나 당신은 더 철저한 (그리고 심지어 철저하지 않은) 대답을 피하는 지혜를 보여주었습니다.
Paul A. Clayton

2
의미있는 측정을 찾는 것은 쉽지 않지만 "일반적인 목적"코드에 대해 더 많은 레지스터의 감소 이점에 약간을 추가하는 것이 좋습니다. Mitch Alsup은 comp.arch에서 16 개가 아닌 x86을 32 개로 확장하면 선택한 8 개에서 16 개까지의 레지스터 확장 (ISTR) 10-15 %에 비해 성능이 약 3 % 향상 될 것이라고 생각합니다. 로드 저장소 ISA의 경우에도 64로 전환하면 최소한 현재 GP 코드에는 거의 이점이 없습니다. (BTW, GPU는 스레드간에 레지스터를 공유하는 경우가 많습니다. 예를 들어 250 개가있는 하나의 스레드는 다른 스레드에 대해 총 16 개의 비공개를 유지합니다.
Paul A. Clayton

종종 고급 언어와 관련된 환경 관리 (따라서 알파 변환)가 실제로는 레지스터 수준에서 사용된다는 것을 알고 싶습니다.
babou

@ PaulA.Clayton 저는 항상 IA-64가 ISA 레지스터가 가장 많은 아키텍처라고 생각했습니다
phuclv

@ LưuVĩnhPhúc SPARC64 VIIIfx는 HPC 전용입니다. 참고로, Am29k ( 1987-8에 소개 )는 Itanium보다 더 많은 GPR 인 64 개의 글로벌 및 128 개의 윈도우 GPR (8 개의 분기 레지스터 및 루프 카운트 레지스터가 있으며 다른 ISA의 GPR에 해당함)을 가지고 있습니다.
Paul A. Clayton

16

레지스터 수를 제한하는 두 가지 이유가 더 있습니다.

  • 예상되는 게인이 거의 없음 : 현재 Intel / AMD x64 모델과 같은 CPU에는 32kByte 이상의 L1-D 캐시가 있으며 L1 캐시에 대한 액세스는 일반적으로 단 하나의 클록주기 (완전한 단일 RAM의 경우 약 100 클록주기에 비해) 만 걸립니다. 접속하다). 따라서 L1 캐시에 데이터를 보유하는 것과 비교하여 레지스터에 더 많은 데이터를 보유하면 얻을 수있는 것이 거의 없습니다
  • 추가 계산 비용 : 레지스터가 많을수록 실제로 컴퓨터 속도가 느려지는 오버 헤드가 발생합니다.
    • 멀티 태스킹 환경에서 작업 스위치는 일반적으로 메모리에 남아있는 프로세스의 모든 레지스터 내용을 저장해야하며 입력 할 프로세스의 내용을로드해야합니다. 레지스터가 많을수록 시간이 오래 걸립니다.
    • 마찬가지로 레지스터 윈도우가없는 아키텍처에서 계단식 함수 호출은 동일한 레지스터 세트를 사용합니다. 따라서 함수 B를 호출하는 함수 A는 B 자체와 동일한 레지스터 세트를 사용합니다. 따라서 B는 사용하는 모든 레지스터의 내용을 저장해야하며 (아직 A 값을 보유 함) 반환하기 전에 다시 기록해야합니다 (일부 호출 규칙에서는 B를 호출하기 전에 레지스터 내용을 저장하는 것이 A의 작업입니다). 오버 헤드는 비슷합니다). 레지스터가 많을수록 절약 시간이 오래 걸리므로 함수 호출이 더 비쌉니다.

L1 캐시에서 어떻게 작동하여 레지스터와 동일한 문제가 발생하지 않습니까?
babou

4
고성능 프로세서에서 L1 Dcache 대기 시간은 일반적으로 3 또는 4주기 (주소 생성 포함)입니다. 예를 들어 인텔의 Haswell은 4주기 대기 시간을 갖습니다 (데이터 종속 레지스터 대기 시간이없는 것도 파이프 라인에 숨기기가 더 쉽습니다). 또한 Dcache는 레지스터 파일 (예 : 파일을 복제 한 Alpha 21264의 경우 4 개의 읽기, 6 개의 쓰기, 4 개의 읽기가있는 2 개의 파일이 1보다 빠름)보다주기 당 더 적은 액세스 (예 : 2 개 읽기, Haswell의 경우 1 개 쓰기)를 지원하는 경향이 있습니다. 8).
Paul A. Clayton

@ PaulA.Clayton : L1 캐시에 3-4 사이클 대기 시간이있는 경우 64 비트 주소 공간이있는 단일 사이클 메모리의 64 워드의 몇 세트가 있으면 이점이있을 수 있습니다. 전용 "로드 / 저장 직접"명령어, 특히 0이 아닌 모든 값을 푸시하는 방법과 0이 아닌 단어를 나타내는 단어가오고 그 다음 다시 팝하는 방법이있는 경우 (팝업되지 않은 모든 레지스터 제로화) . 많은 방법은 16 ~ 60 단어의 지역 변수를 가지므로 3-4 사이클에서 1 사이클로 접근 시간을 줄이는 것이 도움이 될 것입니다.
supercat

@supercat 다양한 스택 (및 글로벌 / TLS [예 : 배낭]) 캐시 아이디어는 서명 버퍼 ( PDF ) 와 같은 메커니즘뿐만 아니라 학술 논문에도 제시되었습니다 . 이로 인해 대화가 어려워집니다 (아마 종료되거나 다른 곳으로 이동해야 함).
Paul A. Clayton

4

많은 코드에는 많은 메모리 액세스가 있습니다 (일반적인 수치는 30 %입니다). 그 중 일반적으로 약 2/3는 읽기 액세스이고 1/3은 쓰기 액세스입니다. 이것은 배열 액세스, 객체 멤버 변수 액세스 등의 레지스터 부족으로 인한 것이 아닙니다.

이것은 C / C ++의 작성 방법으로 인해 메모리 (또는 데이터 캐시)에서 수행되어야합니다 (포인터를 얻을 수있는 모든 것에는 잠재적으로 메모리에 저장해야합니다). 컴파일러가 미친 간접 포인터 트릭을 사용하여 변수에 쓰지 않을 것이라고 추측 할 수 있다면 레지스터에 넣을 것이고 함수 변수에는 훌륭하지만 전역 적으로 접근 가능한 변수에는 적합하지 않습니다 (일반적으로 malloc에서 나오는 모든 것) ()) 지구 상태가 어떻게 변할 것인지를 추측하는 것은 본질적으로 불가능하기 때문입니다.

이 때문에 컴파일러가 어쨌든 약 16 개 이상의 일반 사용 레지스터로 무엇이든 할 수있는 것은 일반적이지 않습니다. 그렇기 때문에 모든 인기있는 건축가가 그 많은 것에 대해 가지고 있습니다 (ARM은 16).

MIPS와 다른 RISC는 32 개를 갖는 경향이 있습니다. 왜냐하면 많은 레지스터를 갖는 것이 그리 어렵지 않기 때문입니다. 비용은 충분히 낮아서 "왜 그렇지 않습니까?"입니다. 32 개 이상은 대부분 쓸모가 없으며 레지스터 파일을 더 오래 액세스 할 수있는 단점이 있습니다 (레지스터 수를 두 배로 늘리면 잠재적으로 멀티플렉서의 추가 레이어가 추가되어 지연 시간이 조금 더 늘어납니다). 또한 명령어의 평균 평균 길이가 약간 길어집니다. 즉 명령어 메모리 대역폭에 의존하는 종류의 프로그램을 실행할 때 추가 레지스터가 실제로 속도를 늦 춥니 다.

CPU가 순서대로 등록 이름을 바꾸지 않고 사이클 당 많은 작업을 수행하려는 경우 (3 회 이상) 이론적으로 사이클 당 연산 수가 증가함에 따라 더 많은 레지스터가 필요합니다. 이것이 Itanium에 레지스터가 너무 많은 이유입니다! 그러나 실제로 부동 소수점 또는 SIMD 지향 코드 (Itanium이 실제로 훌륭했던 코드)와는 별도로 대부분의 코드에는 많은 메모리 읽기 / 쓰기 및 점프가있어주기 당 3 개 이상의 연산을 꿈꾸지 못합니다. (특히 데이터베이스, 컴파일러, 자바 스크립트와 같은 고급 언어 실행, 에뮬레이션 등과 같은 서버 지향 소프트웨어). 이것이 Itanium을 침몰시키는 것입니다.

그것은 모두 계산과 실행의 차이로 귀착됩니다!


2

프로세서에 항상 32 개의 레지스터가 있다고 누가 말 합니까? x86은 8 개, ARM 32 비트 및 x86_64는 16 개, IA-64는 128 개 및 기타 여러 숫자가 있습니다. 당신은 여기를 볼 수 있습니다 . MIPS, PPC 또는 명령어 세트에 32 개의 범용 레지스터가있는 아키텍처조차도 항상 플래그 레지스터 (있는 경우), 제어 레지스터 (이름이 바뀐 레지스터 및 하드웨어 레지스터를 포함하지 않음)가 있기 때문에이 수가 32보다 훨씬 큽니다.

모든 것은 가격이 있습니다. 레지스터 수가 많을수록 작업 전환시 더 많은 작업을 수행할수록 명령어 인코딩에 더 많은 공간이 필요합니다. 레지스터가 적 으면 계산 확장 코드의 레지스터 부족으로 인해 함수를 호출하고 리턴하거나 작업을 전환 할 때 많이 저장 및 복원 할 필요가 없습니다.

또한 레지스터 파일이 클수록 더 비싸고 복잡합니다. SRAM은 가장 빠르고 가장 비싼 RAM이므로 CPU 캐시에서만 사용됩니다. 그러나 여전히 용량이 같은 레지스터 파일보다 훨씬 저렴하고 면적이 적습니다.


2

예를 들어, 일반적인 인텔 프로세서에는 "공식적으로"16 개의 정수 및 16 개의 벡터 레지스터가 있습니다. 그러나 실제로는 더 많은 것들이 있습니다. 프로세서는 "등록 이름 변경"을 사용합니다. reg3 = reg1 + reg2 명령어가있는 경우 reg3을 사용하는 다른 명령어가 아직 완료되지 않은 경우 문제가 발생합니다. 이전 명령어로 읽기 전에 reg3을 덮어 쓰는 경우 새 명령어를 실행할 수 없습니다.

따라서 약 160여 개의 실제 레지스터가 있습니다. 따라서 위의 간단한 명령은 "regX = reg1 + reg2로 변경되고 regX에 reg3이 포함되어 있음을 기억하십시오". 이름 바꾸기 레지스터가 없으면 순서에 맞지 않는 실행은 절대적으로 죽습니다.


1

저는 전기 기술자는 아니지만 레지스터 수를 제한하는 이유는 라우팅이라고 생각합니다. 제한된 수의 산술 단위가 있으며 모든 레지스터에서 입력을 받아 모든 레지스터로 출력 할 수 있어야합니다. 사이클 당 많은 명령을 실행할 수있는 파이프 라인 프로그램이있는 경우 특히 그렇습니다.

이것의 간단한 버전은 복잡성을 가지므로 레지스터 수를 증가시킬 수 없게하거나 더 복잡한 방법으로 모든 것을 라우팅하기 위해 라우팅을 훨씬 더 복잡한 것으로 재 설계해야합니다.O(n2)

나는이 답변에 대한 아이디어를 Mill CPU에 대한 Ivan Godard의 대화 중 일부를 보았습니다. Mill CPU의 혁신 중 일부는 임의의 레지스터로 출력 할 수 없다는 것입니다. 출력은 모두 레지스터 스택 또는 "벨트"로 푸시되므로 출력의 위치를 ​​항상 알기 때문에 라우팅 문제가 줄어 듭니다. 입력 레지스터를 산술 단위로 가져 오는 데 여전히 라우팅 문제가 있습니다.

문제 설명 및 Mill의 솔루션 은 Mill CPU 아키텍처-벨트 (2/9)를 참조하십시오 .


"모든 레지스터에서 입력을 받아 모든 레지스터로 출력 할 수 있어야합니다." -이것은 일반적으로 버스로 구현 될 것으로 예상되며, 모든 레지스터에 대해 ALU에 별도로 연결될 필요는 없습니다.
user253751

1
@immibis : 300 피코 초 안에 데이터를 옮기고 싶다면 버스가 그렇게하지 않을 것입니다. 그리고 많은 양의 데이터를 이동하려는 경우 (예를 들어 두 개의 피연산자로 세 개의 명령어를 수행하고 동일한 사이클에서 각각 하나의 결과를 수행하려는 경우) 버스는 절대적으로 작동하지 않습니다.
gnasher729

0

MIPS ISA, 컴퓨터 조직 및 디자인 제 4 판 , 헤네시 및 패터슨 p. 176은이 특정 질문에 직접 대답합니다.

작을수록 빠릅니다. 속도에 대한 요구는 MIPS가 더 많은 레지스터가 아닌 32 개의 레지스터를 갖는 이유입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.