나는 왜 프로세서가 32 개의 레지스터에서 멈추었는지 궁금했다. 지금까지 가장 빠른 머신입니다. 더 많은 레지스터로 더 큰 프로세서를 만드는 것이 어떻습니까? RAM에 덜가는 것을 의미하지 않습니까?
나는 왜 프로세서가 32 개의 레지스터에서 멈추었는지 궁금했다. 지금까지 가장 빠른 머신입니다. 더 많은 레지스터로 더 큰 프로세서를 만드는 것이 어떻습니까? RAM에 덜가는 것을 의미하지 않습니까?
답변:
첫째, 모든 프로세서 아키텍처가 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 차원 공간에 저장되므로 비트를 저장하는 경우 특정 비트까지의 평균 거리는 입니다. 레지스터 파일은 작은 다중 포트 메모리 및이를 더 크게 만드는 데 따른 제약 중 하나는 결국 더 큰 레지스터 파일을 수용하기 위해 시스템의 클럭을 느리게 시작해야한다는 것입니다. 일반적으로 총 성능 측면에서 이는 손실입니다.
레지스터 수를 제한하는 두 가지 이유가 더 있습니다.
많은 코드에는 많은 메모리 액세스가 있습니다 (일반적인 수치는 30 %입니다). 그 중 일반적으로 약 2/3는 읽기 액세스이고 1/3은 쓰기 액세스입니다. 이것은 배열 액세스, 객체 멤버 변수 액세스 등의 레지스터 부족으로 인한 것이 아닙니다.
이것은 C / C ++의 작성 방법으로 인해 메모리 (또는 데이터 캐시)에서 수행되어야합니다 (포인터를 얻을 수있는 모든 것에는 잠재적으로 메모리에 저장해야합니다). 컴파일러가 미친 간접 포인터 트릭을 사용하여 변수에 쓰지 않을 것이라고 추측 할 수 있다면 레지스터에 넣을 것이고 함수 변수에는 훌륭하지만 전역 적으로 접근 가능한 변수에는 적합하지 않습니다 (일반적으로 malloc에서 나오는 모든 것) ()) 지구 상태가 어떻게 변할 것인지를 추측하는 것은 본질적으로 불가능하기 때문입니다.
이 때문에 컴파일러가 어쨌든 약 16 개 이상의 일반 사용 레지스터로 무엇이든 할 수있는 것은 일반적이지 않습니다. 그렇기 때문에 모든 인기있는 건축가가 그 많은 것에 대해 가지고 있습니다 (ARM은 16).
MIPS와 다른 RISC는 32 개를 갖는 경향이 있습니다. 왜냐하면 많은 레지스터를 갖는 것이 그리 어렵지 않기 때문입니다. 비용은 충분히 낮아서 "왜 그렇지 않습니까?"입니다. 32 개 이상은 대부분 쓸모가 없으며 레지스터 파일을 더 오래 액세스 할 수있는 단점이 있습니다 (레지스터 수를 두 배로 늘리면 잠재적으로 멀티플렉서의 추가 레이어가 추가되어 지연 시간이 조금 더 늘어납니다). 또한 명령어의 평균 평균 길이가 약간 길어집니다. 즉 명령어 메모리 대역폭에 의존하는 종류의 프로그램을 실행할 때 추가 레지스터가 실제로 속도를 늦 춥니 다.
CPU가 순서대로 등록 이름을 바꾸지 않고 사이클 당 많은 작업을 수행하려는 경우 (3 회 이상) 이론적으로 사이클 당 연산 수가 증가함에 따라 더 많은 레지스터가 필요합니다. 이것이 Itanium에 레지스터가 너무 많은 이유입니다! 그러나 실제로 부동 소수점 또는 SIMD 지향 코드 (Itanium이 실제로 훌륭했던 코드)와는 별도로 대부분의 코드에는 많은 메모리 읽기 / 쓰기 및 점프가있어주기 당 3 개 이상의 연산을 꿈꾸지 못합니다. (특히 데이터베이스, 컴파일러, 자바 스크립트와 같은 고급 언어 실행, 에뮬레이션 등과 같은 서버 지향 소프트웨어). 이것이 Itanium을 침몰시키는 것입니다.
그것은 모두 계산과 실행의 차이로 귀착됩니다!
프로세서에 항상 32 개의 레지스터가 있다고 누가 말 합니까? x86은 8 개, ARM 32 비트 및 x86_64는 16 개, IA-64는 128 개 및 기타 여러 숫자가 있습니다. 당신은 여기를 볼 수 있습니다 . MIPS, PPC 또는 명령어 세트에 32 개의 범용 레지스터가있는 아키텍처조차도 항상 플래그 레지스터 (있는 경우), 제어 레지스터 (이름이 바뀐 레지스터 및 하드웨어 레지스터를 포함하지 않음)가 있기 때문에이 수가 32보다 훨씬 큽니다.
모든 것은 가격이 있습니다. 레지스터 수가 많을수록 작업 전환시 더 많은 작업을 수행할수록 명령어 인코딩에 더 많은 공간이 필요합니다. 레지스터가 적 으면 계산 확장 코드의 레지스터 부족으로 인해 함수를 호출하고 리턴하거나 작업을 전환 할 때 많이 저장 및 복원 할 필요가 없습니다.
또한 레지스터 파일이 클수록 더 비싸고 복잡합니다. SRAM은 가장 빠르고 가장 비싼 RAM이므로 CPU 캐시에서만 사용됩니다. 그러나 여전히 용량이 같은 레지스터 파일보다 훨씬 저렴하고 면적이 적습니다.
예를 들어, 일반적인 인텔 프로세서에는 "공식적으로"16 개의 정수 및 16 개의 벡터 레지스터가 있습니다. 그러나 실제로는 더 많은 것들이 있습니다. 프로세서는 "등록 이름 변경"을 사용합니다. reg3 = reg1 + reg2 명령어가있는 경우 reg3을 사용하는 다른 명령어가 아직 완료되지 않은 경우 문제가 발생합니다. 이전 명령어로 읽기 전에 reg3을 덮어 쓰는 경우 새 명령어를 실행할 수 없습니다.
따라서 약 160여 개의 실제 레지스터가 있습니다. 따라서 위의 간단한 명령은 "regX = reg1 + reg2로 변경되고 regX에 reg3이 포함되어 있음을 기억하십시오". 이름 바꾸기 레지스터가 없으면 순서에 맞지 않는 실행은 절대적으로 죽습니다.
저는 전기 기술자는 아니지만 레지스터 수를 제한하는 이유는 라우팅이라고 생각합니다. 제한된 수의 산술 단위가 있으며 모든 레지스터에서 입력을 받아 모든 레지스터로 출력 할 수 있어야합니다. 사이클 당 많은 명령을 실행할 수있는 파이프 라인 프로그램이있는 경우 특히 그렇습니다.
이것의 간단한 버전은 복잡성을 가지므로 레지스터 수를 증가시킬 수 없게하거나 더 복잡한 방법으로 모든 것을 라우팅하기 위해 라우팅을 훨씬 더 복잡한 것으로 재 설계해야합니다.
나는이 답변에 대한 아이디어를 Mill CPU에 대한 Ivan Godard의 대화 중 일부를 보았습니다. Mill CPU의 혁신 중 일부는 임의의 레지스터로 출력 할 수 없다는 것입니다. 출력은 모두 레지스터 스택 또는 "벨트"로 푸시되므로 출력의 위치를 항상 알기 때문에 라우팅 문제가 줄어 듭니다. 입력 레지스터를 산술 단위로 가져 오는 데 여전히 라우팅 문제가 있습니다.
문제 설명 및 Mill의 솔루션 은 Mill CPU 아키텍처-벨트 (2/9)를 참조하십시오 .