CSAPP 4.3 Sequential Y86-64 Implementations
·983 words·5 mins
📝 상세 정리 # 이제 순차적 프로세서 (SEQ)를 먼저 만들 것이다. 각 클록사이클에서, 완전한 명령어를 처리하는 모든 단계를 수행한다. 그래서 느릴 것이다! 4.3.1 Organizing Processing into Stages # 일반적으로, 명령어 처리에는 여러 연산이 수반된다. 우리는 그 모든 명령어가 일관된 단계 시퀀스를 따르도록 하고싶다. 과정은 다음과 같다 Fetch PC를 메모리주소로 사용하여 명령어 바이트 읽기 icode / ifun / 레지스터 지정자 / valC 등을 읽기 valP는 다음 명령어 주소 = PC의 값에 읽은 명령어의 길이를 더한 값 Decode 레지스터파일에서 최대 두개의 연산자를 읽어서 valA / valB 제공 Execute 명령어에 의해 지정된 연산을 수행하거나, 메모리 참조의 주소를 계산하거나, 스택포인터를 증가/감소하는 등. 이 값을 valE라고 한다. 조건 플래그가 설정 / 평가하는것도 여기 Memory 메모리에 데이터를 쓰거나 메모리에서 데이터를 읽어오기 그 값을 valM이라고 한다. Write back 최대 두개의 결과를 레지스터 파일에 쓰기 PC update PC를 다음 명령어 주소로 업데이트. 프로세서는 위 과정을 무한히 반복한다. 예외가 발생할때 정지한다 halt / 유효하지 않은 명령어 / 유효하지 않은 주소 등 보다 완전한 설계에서는 예외처리 모드에 진입해서 특수 코드를 실행 과정이 되게 많게 느껴지지만, 저렇게 전체 흐름을 유사하게 해야 하드웨어의 양을 최소화하고 복잡성을 줄일 수 있다. 서로 다른 명령어가 가능한 많은 하드웨어를 공유하도록 한다거나.. 하드웨어에서 논리블럭을 중복하는 비용은 소프트웨어에서 코드블럭을 중복하는거보다 훨씬 비싸니까! 4.3.2 SEQ Hardware Structure # 모든 Y86-64 명령어들은 위의 6단계의 연속으로 조직화할 것이다. 하드웨어적으로 위의 6단계는 어떻게 구성되는가? Fetch PC 레지스터를 이용해서 명령어 바이트 읽기, valP 계산 Decode 레지스터 파일의 두개의 읽기포트를 통해 valA, valB를 동시에 읽는다. Execute 명령어 유형에 따라 arithmetic / Logic ALU 유닛을 다양하게 사용한다. 그중에 입력중 하나에 0을 더하여 출력으로 전달하는 더미 adder도 있다! CC (Condition Code Register) 세개의 조건 코드 비트를 보유함 새로운 값은 ALU에 의해 계산되고, 조건부 이동 명령어를 실행할 때 목적지 레지스터를 업데이트할지를 계산함. 점프같은것도 마찬가지. Memory 메모리의 워드를 읽거나 씀. 명령어 메모리와 데이터 메모리는 그림에서는 다르게 그리지만, 결국 하나의 메모리에 엑세스하는것임 Write back 레지스터파일의 두개의 쓰기 포트로 데이터를 작성 포트 E는 ALU의 계산 결과를 쓰기 위해, 포트 M은 데이터 메모리에서 읽은 값을 쓰기 위해 사용 그림으로 나타낼때 관례 클럭 레지스터는 흰색 직사각형 (SEQ에서는 PC가 유일한 크럭 레지스터이다) 하드웨어 유닛은 연한 파란색 사각형 제어 로직 블럭은 회색 둥근 사각형 와이어 이름은 흰색 원 (라벨) 워드는 중간두께 선, 바이트는 얇은선, 단일비트는 점선 4.3.3 SEQ Timing # SEQ는 조합기와 두가지 형태의 메모리 장치(클록 레지스터, 랜덤 액세스 메모리)로 구성된다. 조합기는 시퀀싱이나 제어 없이, 입력이 변경될때마다 논리게이트 네트워크를 통해 전파된다. 랜덤 엑세스 메모리에서 데이터를 읽어오는 과정은 주소 입력에 기반하여 계산된다고 봐도 된다. 레지스터 파일에서는 합리적이고, 더 큰 회로에서도 특수한 클록 회로를 이용해서 이를 모방할 수 있다. 써있는 말이 좀 복잡한데, 그냥 회로 관점에서 어차피 쓰기도 클록 엣지에서만 일어나고, 읽기는 주소를 넣으면 데이터가 나오는 과정이니까 조합 논리 블록이랑 다를게 없다는 말인 것 같다. 명령어 메모리는 명령어 읽기 전용으로만 사용되므로, 이 유닛 자체를 조합기로 생각할 수 있다. 이렇게 생각하면, 시퀀싱에 대해 명시적으로 제어가 필요한건 PC, 조건코드 레지스터, 데이터 메모리, 레지스터 파일 4가지가 남는다. 이들은 클록신호 하나를 통해 제어되고, 레지스터에 값을 로드하고 랜덤액세스 메모리에 값을 쓰는 타이밍을 트리거한다. PC는 매 클록 사이클마다 새로운 명령어 주소를 로드하고, 조건코드 레지스터는 OPq에서만 로드되고, 데이터메모리는 rmmovq, pushq, call에서만 쓰이고… 레지스터 파일의 쓰기 포트는 매 사이클마다 두개의 프로그램 레지스터를 업데이트할 수 있지만, 특수 레지스터 ID인 0xF를 포트주소로 사용해서 쓰기가 없도록 할 수 있다. 이러한 클록ing는 시퀀싱을 제어하는데 꼭 필요한 것들이다. 원칙: No reading back 프로세스는 명령어 처리를 완료하기 위해 해당 명령어에 의해 업데이트 된 상태를 읽을 필요가 없다.