마이크로 프로세서에 더 많은 레지스터가없는 이유는 무엇입니까?


18

레지스터는 이론적으로 필요하지 않습니다. 모든 마이크로 프로세서는 여전히 레지스터없이 작동합니다. 그러나 이처럼 간단한 추가 작업은 마이크로 프로세서를보다 효율적으로 만드는 데 도움이되었습니다.

더 많은 레지스터를 가져 와서 더 많은 이점을 얻을 수없는 이유는 무엇입니까? 그것들은 단지 메모리상의 칩 이고 추가하기가 그리 어렵지 않다고 상상할 수 있습니까? 레지스터의 수에 영향을 미치는 요인은 무엇이며 현재보다 10 배나 더 많습니까?


8
@ Alper91 가정적이고 실제적인 많은 아키텍처에는 레지스터가 없으므로 전혀 필요하지 않습니다. 단순히 유용한 최적화입니다.
파이프

4
흠. 스팍에 대해서는 아무도 언급하지 않았습니다. 가장 큰 구현은 520 개의 레지스터를 가질 수 있습니다 (32 개의 창에 16 개의 레지스터, + 8 개의 전역). 나는 그것들을 기억합니다.
jonk

13
레지스터를 지정 해야하는 명령어의 비트 수는 큰 문제라고 생각합니다. 1024 개의 레지스터가있는 경우 모든 산술 명령어에 대해 최소 30 비트가 필요합니다. "3 개의 레지스터가 모두 같은 32 개 그룹의 그룹 (이 경우 20 비트 필요)과 같은 다른 제약 조건을 추가하지 않는 한
user253751

8
@pipe-실제로 거의 모든 실제 디자인에는 회로도에서 "레지스터"가 필요합니다. 스택 머신이나 이와 유사한 것을 빌드하더라도 ALU에 대한 인수 또는 다른 출력을 유지할 수있는 공간이 있어야합니다. -대부분의 메모리에는 3 개의 액세스 포트가 없습니다. 그리고 스택 머신에는 스택 포인터 가 필요합니다 . 레지스터입니다! 파이프 라인 레지스터는 언급하지 않습니다. 프로그래머로부터 이러한 "레지스터"의 사용을 숨길 수는 있지만 여전히 원시 레지스터 머신만큼이나 일부가 필요할 수도 있습니다.
Chris Stratton

4
@ChrisStratton 물론, ISA를 통해 노출되지 않는 한 단순히 구현 세부 사항입니다. 레지스터가 의미하는 OP를 알지 못하기 때문에 다소 의미없는 논쟁 .
파이프

답변:


33

몇 가지 요인이 있습니다.

  • 고성능 마이크로 아키텍처는 레지스터 이름 변경을 사용합니다. 즉, 물리적 레지스터의 수는 아키텍처 상으로 보이는 레지스터의 수보다 많으며 독립적 인 용도를 추적 할 수 있습니다.

  • 레지스터 수를 두 배로 늘려도 성능이 두 배가되지는 않습니다. 16 개에서 32 개의 레지스터로 증가하는 ISTR ( 컴퓨터 아키텍처의 A Quantitative Approach )은 증가가 악영향을 미치지 않는다고 가정 할 때 (매우 낙관적 인 가정) 10 %의 개선을 가져옵니다.

  • 구조적으로 보이는 레지스터에는 비용이 있습니다. 예를 들어 :

    • 숫자를 늘리면 명령 형식에서 취한 비트 수가 증가하여 어떤 레지스터가 작동 중인지 나타냅니다 (레지스터 수가 두 배가되면 형식에 레지스터 당 하나 이상의 비트가 있음을 의미하므로 해당 비트를 다른 용도로 사용하거나 강제로 사용하지 못하도록 함) 더 긴 명령어 크기).
    • 아키텍처 레지스터 수를 늘리면 컨텍스트 전환 비용이 증가합니다 (컨텍스트 전환시 저장 및 복원해야 함).

1
16 개에서 32 개 레지스터의 성능 향상은 문제가되는 컴파일러의 최적화 가능성에 전적으로 달려 있다고 생각합니다. 어셈블러에서 (x64 아키텍처의) 레지스터 수의 두 배에 액세스하면 성능이 크게 향상 될 수 있지만 틈새 역할 및 실제로 사용되는 경우에만 가능합니다.
rdtsc

6
@rdtsc : 8 개에서 16 개의 아키텍처 레지스터로 이동하면 이 답변과 연결된 논문의 시뮬레이션 데이터에 따라 일반적인 코드의 스필 / 리로드 양이 크게 향상됩니다 . 코드 크기, 명령어 수 및 지연 시간이 짧은 저장소 전달의 중요성에 영향을줍니다. 16-> 32는 훨씬 작은 효과입니다. AFAICT, 16 개의 아키텍처 레지스터는 레지스터 이름을 바꾸어 WAR 및 WAW 위험을 제거하는 하드웨어에 적합합니다.
Peter Cordes

2
그러나 인텔의 AVX512는 총 32 개의 벡터 레지스터를 16 개 더 추가합니다 (전체 캐시 라인의 너비를 64 바이트로 두 배로 늘림). 처리량이 많은 대기 시간 FP 작업에서 대기 시간을 숨기려면 많은 레지스터가 필요할 수 있습니다. 예를 들어, Intel Haswell은 0.5c 처리량 FMA 당 1 개의 5c 위도를 갖기 때문에 감소를 위해 FMA 실행 단위를 포화시키기 위해 10 개의 벡터 누산기가 필요합니다 (예 : 도트 제품 또는 어레이 합산, FMA는 루프로 전달되는 종속성의 일부 임) ). x86-64에는 16 개의 벡터 레지스터 만 있습니다. 그러나 정수 연산, 특히 sp. GP reg에서는 1c 이상의 대기 시간이 거의 없습니다.
Peter Cordes

1
정수, FP 및 벡터 레지스터의 절충은 다릅니다. 예를 들어 정수 레지스터의 게으른 저장 / 복원은 의미가 없으므로 벡터 1에 대해 수행하는 것이 훨씬 좋습니다. 그리고 벡터 ISA는 종종 정수 1보다 많은 레지스터를 가지고 있습니다 (AltiVec은 적어도 128 개, ISTR은 Sparc에 대해 256 개를 읽었지만 지금은 참조를 찾을 수 없습니다).
AProgrammer

1
en.wikipedia.org/wiki/AltiVec 에는 32 개의 128b 벡터 조절기가 있습니다. SPARC에 대해 궁금해서 레지스터 창 항목이 컨텍스트 전환에 어떻게 작동하는지 찾아 보았습니다. 한 번에 32 개의 레지스터를 볼 수 있지만 더 큰 레지스터 파일에 슬라이딩 윈도우를 사용합니다. 그것은 소리 이 단순화 된 버전의 운영 체제와 같은 그것을 저장 / 복원하기 위해 전체 슬라이딩 윈도우 레지스터 파일의 크기를 알 필요가 윈도우 슬라이드 지시가 필요한 경우 REGS 복원 / 저장하기위한 메모리를 제공하더라도 때문에, 그것은 트래핑에 의해 이루어집니다 OS에.
Peter Cordes

16

레지스터와 RAM은 모두 메모리이지만 액세스하는 비용 (칩 영역 또는 숨겨진 클럭 사이클)을 반영하기 위해 서로 다른 방식으로 액세스됩니다.

레지스터는 ALU에 밀접하게 바인딩되어 있으며 데이터 소스, 싱크, 수정 자 등의 많은 역할을 수행 할 수 있습니다. 따라서 다양한 다중 연결이 필요합니다. 일부 아키텍처에서는 R1 <= R2 + R3을 쓸 수 있으며, 이는 단일 클록 사이클에서 정확히 발생합니다. 각 레지스터는 op 코드로 직접 주소 지정되며이 주소 지정은 매우 제한적인 리소스입니다.

레지스터를 구현하는 데 비용이 많이 들기 때문에 대부분의 아키텍처에서이 수는 일반적으로 10/20 정도로 제한됩니다.

RAM은 CPU에 느슨하게 바인딩되어 있으며 일반적으로 단일 공유 연결을 통해 채널링됩니다. 따라서 많은 양의 RAM을 구현하는 것이 훨씬 저렴합니다. RAM 주소는 일반적으로 레지스터 저장 주소에서 가져 오므로 큰 명령 폭을 소비하지 마십시오.

SPARC는 72에서 640 개의 64 비트 레지스터를 가진 흥미로운 아키텍처로, 매개 변수 전달을 통해 빠른 서브 루틴 호출을 위해 겹치도록 이동할 수있는 32 개의 레지스터 컨텍스트를 갖습니다. 99.999 %의 응용 프로그램과 같이 비용이 중요한 PC 및 서버에서는 찾지 못하는 경향이 있습니다.


4
또 다른 측면은 컨텍스트 전환 중에 레지스터를 저장 / 복원해야한다는 것입니다. 더 많은 레지스터, 더 많은 시간.
Michel Billaud

나는 이전 TMS9900 외부 메모리에 모든 작업 레지스터 유지 있습니다 것 en.wikipedia.org/wiki/Texas_Instruments_TMS9900
피터 스미스

1
나는 (몇 가지 조정을 제외하고) '불변'으로 자격을 얻었지만 단순화하기 위해 꺼내 었습니다. 아마도 나는 그것을 '일반적으로'변경 할 것입니다. 기본적으로 예외를 찾아서 이해할 수 있으면 예외를 지적 할 필요가 없습니다. 당신이 오해되기에 충분히 미묘하다면, 그것은 당신을 곤경에 빠뜨리지 않기 때문에 중요하지 않습니다. 사악한 TMS9900, 나는 초기 생애의 이상한 죄수를위한 99/4의 죄를 지었다!
Neil_UK

Itanium에는 등록 창이 있습니다.
Simon Richter

1
@ChrisStratton : "ABI"의 일부로 간주되는 "레지스터 X 및 Y를 사용할 수 없습니다"(예 : 밉의 k0 및 k1 레지스터)에 대한 선례가 있지만 일반적이지 않습니다. 컨텍스트 스위치에서 이러한 "ABI 금지 레지스터"의 저장 / 복원이 수행되지 않으면 프로세스간에 원치 않는 / 안전하지 않은 비밀 메시징 채널이 있습니다. 즉, 통신 할 수없는 프로세스는 금지 된 레지스터에 정보를 저장하고 컨텍스트 스위치를 대기함으로써 그렇게 할 수있다.
R ..

12

레지스터는 지시 사항 내에서 주소를 지정해야합니다. 레지스터가 많으면 명령이 더 깁니다. 많은 레지스터가있는 경우 인터럽트 서비스에 대한 레지스터 컨텐츠를 저장하고 복원하는 데 더 많은 시간이 필요합니다.


5

대부분의 경우 레지스터 수는 비용, 복잡성 및 유용성 사이의 절충입니다.

레지스터는 다중 포트 정적 RAM으로 구현되므로 다른 스토리지 옵션보다 비용이 많이 듭니다 (칩 영역).

그런 다음 프로세서의 명령어 세트와 결합하여 레지스터 수를 늘리면 명령어 세트의 복잡성이 증가합니다. 따라서 명령어 세트와의 호환성을 유지하려면 효율성을 높이기 위해 차세대 프로세서에서 사용할 수있는 레지스터 수만 늘리면 프로그램에서 사용할 수 없습니다.

다음은 실제로 필요한 레지스터의 양입니다. 유용성에는 한계가 있습니다. 1024 바이트에서 수학 연산을 수행하는 알고리즘을 작성한다고 가정 해 보자.

load operand1=5
load address
loop: load operand2=byte1@address
multiply Register1 with Register2
store result
increment address
if address = end goto endLoop
jump loop
endLoop:

이제 1024 개의 레지스터와 모든 데이터가 저장된 경우 프로그램은 다음과 같습니다.

multiply Register1 with Register2
multiply Register1 with Register3
multiply Register1 with Register4
multiply Register1 with Register5
multiply Register1 with Register6
...

그들 각각은 다른 지시이기 때문에, 그들 각각의 하나를 작성해야합니다. 필요한 프로그램 메모리가 폭발하고 있습니다. 이를 실현 한 후 다음과 같은 지침을 소개 할 수 있습니다 multiply register1 with register(2 to 256). 그러나 언제 멈추겠습니까? 모든 조합에 대한 지침을 제공합니까?

따라서 현재 사용 가능한 숫자는 비용, 복잡성 및 유용성 간의 훌륭한 균형입니다.


1
multiply Register1 with Register2 multiply Register1 with Register3데이터는 컴퓨터 외부에서 직접 또는 간접적으로 가져와야하므로 레지스터를로드해야하고 결과를 직접 또는 간접적으로 어딘가에 사용해야하므로 레지스터를 저장해야하므로 프로그램 은 매우 비현실적 이라고 생각 합니다. 실제로, 고급 언어를위한 알맞은 최적화 컴파일러는 첫 번째 프로그램의 루프를 '언 롤링'하여 두 번째 프로그램과 같은 것을 만들어 레지스터 사용, 메모리 대기 시간, 캐시 점유 및 실행 속도를 최적화합니다.
gbulmer

1
많은 특수 목적 multiply register1 with register(2 to 256)지침이 필요하지 않습니다 . 파이프 라이닝은 특히 명령을 더 쉽게 디코딩하고 실행할 수 있도록 CPU 처리량을 크게 향상시킵니다. 따라서 실행 속도가 높은 몇 가지 간단한 명령을 사용하여 복잡하고 방대한 명령의 효과를 얻을 수 있습니다. 더 많은 수의 레지스터를 사용하면 컴파일러가 독립적 인 여러 명령 (레지스터를 공유하지 않는 명령)을 생성 할 수있어 독립적으로 완료 할 수있어 처리량이 향상됩니다. 귀하의 예 = 더 많은 레지스터가 더 좋습니다.
gbulmer

4

레지스터는 매우 비싸다. 매우 비싸다. 레지스터 자체는 그리 많지 않으며 레지스터와의 모든 연결입니다. reg1 = reg2 + reg3 명령이 있다고 가정 해보십시오. 이 빠른 구현 을 위해서는 한주기에서 두 레지스터의 데이터를 읽고 두 번째주기에서 다른 레지스터에 쓰십시오. 이제 사이클 당 여러 명령을 실행할 수있는 프로세서 (예 : 3 개의 명령)가 있으면 사이클 당 6 개의 레지스터에서 데이터를 읽고 3 개의 레지스터에 데이터를 쓸 수 있어야합니다. 그것은 끔찍하고 끔찍한 매우 빠른 연결입니다.

물론 더 많은 트랜지스터를 사용할 수 있습니다. 문제는 : 속도가 느려집니다. 더 많은 레지스터에서 선택하려면 더 많은 하드웨어가 필요합니다. 레지스터 파일의 공간이 커집니다. 모든 것이 느려집니다. 따라서 동일한 기술을 사용하면 16 개의 레지스터를 사용하여 2,600MHz에서 실행하거나 32 개의 레지스터를 사용하여 2,400MHz에서 실행할 수 있습니다. 이제 추가 레지스터가 클럭 속도를 크게 떨어 뜨려야합니다.


2

레지스터 수에 영향을 미치는 요인

- 메모리 계층

레지스터, 캐시, RAM은 모두 다른 스토리지 기술로 구현됩니다.

다른 기술은 다릅니다

  1. 접근 시간
  2. 비용
  3. 밀도

예 : CPU에서 발견 된 내부 레지스터는 정적 랜덤 액세스 메모리 이고 컴퓨터 메인 메모리는 동적 랜덤 액세스 메모리입니다.

정적 RAM 이진 셀은 6 트랜지스터 회로를 사용하여 구현되고 동적 RAM 이진 셀은 커패시터와 트랜지스터를 사용하여 구현됩니다. SRAM과 DRAM 비교

  • SRAM 메모리는 DRAM 메모리보다 훨씬 빠릅니다 [DRAM에 비해 SRAM에 액세스하는 데 몇 사이클이 걸립니다]
  • SRAM 회로는 DRAM보다 적은 전력을 소비합니다
  • DRAM은 SRAM과 달리 메모리의 모든 비트를 주기적으로 갱신해야합니다.
  • SRAM은 DRAM보다 더 비싸다
  • SRAM은 DRAM에 비해 밀도가 낮습니다

따라서 빠르고 비싸고 밀도가 낮은 메모리의 수를 늘리는 것은 실용적이지 않습니다. 실제로 우리는 그중 몇 가지를 사용할 수 있으며 잘 작성된 프로그램은 가장 자주 사용되는 데이터를 이러한 빠른 레지스터에 저장하고 덜 자주 사용하는 데이터는 느린 메모리에 저장합니다.

- 지시 길이

레지스터의 주소는 명령어에 포함되며,이 주소는 주소를 나타낼 수있는 비트 수에 따라 액세스 가능한 레지스터의 수를 제한합니다. 예를 들어 MIPS 아키텍처에서 32 비트 길이 명령어는 5 비트 만 보유하여 레지스터 수를 2 5 = 32 레지스터로 제한하는 액세스 가능한 레지스터의 주소를 나타냅니다 . 레지스터 수를 늘리려면 모든 레지스터에 액세스 할 수있는 충분한 비트를 포함하기 위해 명령어 길이를 늘려야합니다.


2

프로세서의 명령어 세트를 살펴보면 여러 가지 방법으로 그룹화 할 수 있습니다. 예를 들어, 모든 ADD지시 사항과 모든 지시 사항이 함께 그룹화 될 수 있습니다 XOR.

동일한 명령어의 각 그룹 내에는 메모리 또는 레지스터에서 작동하는 버전이있을 수 있습니다. 프로세서가 갖는 레지스터 수를 효과적으로 정의하는 것이이 하위 그룹입니다.

8 비트 가상 예를 들어,하자가 말하는 $Ax지침이 될 수있는 ADD지침 및 $Cx수 있습니다 XOR지침. 이 디자인에서는 피연산자를 정의하기 위해 4 비트 만 남았습니다!

  • 하나는 4 개의 범용 레지스터 만 가질 수 있으며 2 비트를 사용하여 하나를 정의하고 2 비트를 사용하여 다른 하나를 정의 할 수 있습니다.
  • 또는 첫 번째 비트를 사용하여 "특수"변형을 구분하고 다른 3 비트를 사용하여 누산기와 함께 작동 할 8 개의 레지스터 ( $x0어큐뮬레이터 자체 일 수 있음) 를 정의 할 수 있습니다.
  • 또는이 레지스터 수보다 많은 레지스터를 가질 수 있지만 어떤 레지스터에 어떤 명령어를 액세스 할 수 있는지 제한합니다.

물론, 우리는 8 비트 명령어 세트를 지났습니다. 그러나 여전히이 논리는 과거에 레지스터 세트를 정의하는 데 도움이되었으며 앞으로도 계속 그렇게 할 것입니다.

편집 (요청에 따라)

4 비트는 명령을위한 상단을 말 : ADD, SUB, XOR, MOV, CMP등 여기에 16 가능성이 있습니다. 그런 다음, 등록 - 투 - 레지스터 그 지침 (예를 들면 의미가 있습니다 ADD Rx,Ry, 당신은 지정해야합니다) RxRy. 다음 두 비트는 용 x이고 마지막 두 비트는 용 입니다 y. 그러므로:

ADD R1, R2  =>  'ADD' + 'R1' + 'R2' => $A0 + $04 + $02

이와 같이 레지스터를 정의하는 데 2 ​​비트 만 있으면 총 4 개의 레지스터를위한 공간 만 있습니다!

따로, 일부 레지스터 조합은 의미가 없습니다. 예를 들어 MOV Rx, Rx(아무것도하지 않음) 및 SUB Rx, Rx(항상을 생성 함 0). 이것들은 특별한 경우가 될 수 있습니다.

  1. SUB Rx, RxNOT Rx단일 연산자 명령 이 될 수 있습니다.
  2. MOV Rx, RxMOV로 해석되는 즉각적인 값으로 두 번째 바이트를 취하는 명령 이 될 수 MOV Rx, #$yy있습니다.

이런 식으로 명령어 맵으로 "플레이"하여 프로그래머에게 더 큰 명령어 세트를 제공하기 위해 쓸모없는 명령어 나 의미없는 명령어를위한 구멍을 채울 수 있습니다. 그러나 궁극적으로 명령어 세트는 레지스터 세트를 정의합니다.


나는 여전히 혼란스러워, 피연산자에 4 비트 만 남은 것을 설명 할 수 있습니까?
Darshan Chaudhary

업데이트 된 답변 확인
John Burger

1
IMHO이 대답은 " 가설적인 예제에서 8 비트 명령어 세트로 가정 "을 질문의 시작 부분 으로 이동하여 크게 개선 될 것 입니다. 나는 그것을 이해하려고 노력하는 데 시간을 낭비하고, 8 비트, 고정 길이 명령에만 적합하다고 결론 내렸다. IMHO, 이러한 종류의 명령 집합은 질문의 맥락에서 관련이 없습니다. 전체 주소 공간은 정적 RAM과 밀접하게 연결될 수 있습니다. 또한 " 일부 레지스터 조합이 의미 가 없습니다 ... "로 시작하는 부분 은 질문과 관련이 없으며 삭제할 수 있다고 생각합니다. 내 $ 0.02
gbulmer

-2

인텔은 현재 CPU 코어 당 수백 개의 레지스터를 사용하고 있습니다. 그러나 CPU에 저장된 가장 많은 양의 데이터는 캐시에 있으며 이는 간접적으로 질문에 대답합니다. 캐시는 작은 고속 L1 캐시와 더 느린 L2 및 L3 캐시와 함께 계층으로 구성됩니다. 어떤 의미에서 레지스터 파일은 L0이며, L1보다 훨씬 빠르지 만 더 작습니다. 따라서 레지스터 수를 늘릴 수 있지만 속도가 느려질 수 있습니다.

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