업데이트:

태그:

카테고리:

들어가며

컴퓨터의 성능은 명령어 개수, 클럭 사이클 시간 그리고 명령어당 클럭 사이클 수에 의해 결정됩니다.
여기서 클럭 사이클 시간과 명령어당 클럭 사이클 수(CPI)는 프로세서의 구현 방법에 의해 결정됩니다.
간단하게 명령어 하나가 끝날때까지 다른 명령어들을 멈추게하는 stall은 구현은 간단하지만, 느리다는 단점이 있습니다.
그래서 pipelined processor의 개념이 등장했고, CPU의 각 구성요소들이 1 cycle에 다른 명령어들의 stage를 수행하게끔 설계되어있습니다.
그래서 복잡……하지만 공부해야하죠


만들어질 프로세서

이번에 공부하면서 최종적으로 만들 프로세서는 다음과 같습니다.


1. Instruction Memory + Register + ALU

왼쪽 구성요소부터 살펴보면…

  • 설명
    • PC: PC는 fetch단계에서 IM에 읽을 주소를 전달하고, + 4로 IM에서 다음 명령어의 위치를 가리키고 있습니다.
    • IM: PC로부터 IM에서 읽을 명령어의 주소를 받고, Registerfile에 명령어를 전달합니다.
    • Register file: RegisterFile은 2개의 read port, 1개의 write port로 명령어를 decode해서 ALU에 전달합니다.
    • ALU: ALU는 Register File에서 값을 받아 연산을 하게됩니다.


  • 제어신호
    • RegWrite: 레지스터에 값을 쓸지 말지 결정합니다. add의 경우에는 레지스터에 값을 써야하는 연산이며, lw는 레지스터에 값을 쓰지않는 연산이기에 필요합니다.
    • ALU control: ALU에서 어떤 연산을 하는지 결정하는 4bit 신호입니다. add는 0000, lw0010입니다.


2. I-format(addi) + Data memory(DM)

  • 설명
    • DM: 프로세스가 사용하는 메모리 공간입니다. 데이터를 읽거나(mem read), 데이터를 쓸 수 있습니다(mem write).
  • 제어신호
    • ALUSrc: ALU의 피연산자 중 한개가 레지스터가 아닌, 상수값일 때 1이됩니다. I format에서 addi와 같은 연산의 경우, 16bit에 상수값이 저장되어있기때문에 sign extend를 하게됩니다.
    • memread: 메모리로부터 데이터를 읽어오는 동작을 수행할 때 사용됩니다. 만약 memread가 1로 설정되어 있으면, 메모리에서 데이터를 읽어와 레지스터에 저장합니다.
    • memtoreg: 메모리로부터 읽어온 데이터를 레지스터에 쓸 때 사용됩니다. 만약 memtoreg가 1로 설정되어 있으면, 메모리에서 읽어온 데이터(memread한 데이터)를 레지스터에 쓰도록 지시합니다.
    • memwrite: 이 신호는 메모리에 데이터를 쓰는 동작을 수행할 때 사용됩니다. 만약 memwrite가 1로 설정되어 있으면, 레지스터에 저장된 데이터를 메모리에 쓰도록 지시합니다.


3. I-format(Branch)

  • 설명
    • I-format에서 addi는 sign-extend된 값을 바로 연산하지만, branch는 PC+4에 sign-extended, ssl 2 된 값을 연산해야합니다.
    • 따라서, shift left하는 유닛, 이 값을 PC + 4와 더하는 유닛, 그리고 다음 명령어가 PC+4인지, PC + 4 + (sign-extended 16bit) << 2결정하는 유닛이 추가되어야합니다.
  • 제어신호
    • Branch: 해당 명령어가 Branch인지 아닌지 결정합니다. branch instruction이 I-format이기때문에 필요합니다.
    • PCSrc: 다음 명령어의 위치를 결정합니다. branch-taken인 경우, branch not taken인 경우가 있습니다. Register File 우측의 ALU의 Zero 신호가 branch-taken인지 not taken인지 결정하게됩니다.


4. J-format(Jump, Jal)

  • 설명
    • J-format은 다음 instruction을 PC+4[31~28] + 26bit address + ssl 2 된 값으로 하게됩니다.
    • 따라서, shift left하는 유닛, 다음 명령어가 PC+4인지 위의 값인기 결정하는 유닛이 추가로 필요합니다.
  • 제어신호
    • Jump: 해당 명령어가 jump instruction인지 아닌지 결정하게됩니다. 다음 instruction을 결정할때 필요합니다.
    • ALUop: ALU에서 연산할 명령의 종류를 결정합니다.
    • RegDst: ALU의 연산결과를 format의 rd에 저장할지, rt에 저장할지 결정합니다. add의 경우에는 rd에 저장하므로 1, addi는 i-format에서 rt에 저장해야하므로 0입니다. sw, beq와 같이 연산결과를 레지스터에 값을 저장하는 연산이 아닌경우에는 don't care가 적용되어 사용되지 않습니다.

cs.umd.edu



파이프라이닝

개념

  • ILP: Instruction Level Parrarel 여러 명령어가 중첩되어 실행되는 프로세서 구현기술입니다.
  • 파이프라이닝에서 가장 중요한 점은 total throughput을 늘릴 수 있다는 것이지, 단일 명령어 하나하나의 시간을 줄일수는 없다는 것입니다.

  • 전통적인 mips명령어는 5개의 stage가 있습니다.
    • IF :IM에서 명령어를 가져온다.
    • ID: 명령어를 해독과 동시에 레지스터를 읽는다.
    • EX : 연산을 수행하거나, 주소를 계산합니다.
    • MEM : 데이터 메모리에 있는 피연산자에 접근합니다.
    • WB : 레지스터에 값을 쓴다.


그림으로 이해하기

  • 파이프라이닝되지 않은 경우와 된 경우의 실행을 비교합니다.
  • 1번째 instruction의 종료시간은 파이프라이닝되지 않은 경우가 더 빠르게 끝납니다.
  • 파이프라이닝을 하면 모든 stage의 cycle time이 가장 느린 stage로 맞춰지기때문입니다.
  • 하지만, 프로그램의 명령어의 개수가 많으면 많을수록 파이프라이닝의 효과는 극대화됩니다.
  • 개별 명령어의 처리시간은 증가하지만, 전체 프로그램의 처리시간은 감소하는 것을 확인할 수 있습니다.


계산식들

  • 이상적인 파이프라이닝된 명령어 사이 시간은 다음과 같숩니다,
  • stage의 cycle time이 모두 완벽하게 balanced되어있다면 1개 instruction 처리시간 / stage개수이지만, 현실에서는 매우 어렵습니다.
    파이프 라이닝된 명령어 사이 시간 = non-pipelined된 명령어 사이 시간 / 파이프 단계 수
    
  • cycle time
    cycle time == pipeline stage중 가장 오래걸리는 stage의 시간
    


  • 프로그램의 전체 cycle를 계산하는 식은 다음과 같습니다.
    program에 실행 필요한 cycle = pipeline stage개수 + (total instruction - 1)
    


  • 전체 시간을 계산하기 위해서는 위의 total cycle에 가장 느린 stage의 처리시간 cycle time을 곱하면됩니다.
    total time = (num of pipeline stage + (total instruction - 1)) * max(cycle time of stages)
    



파이프라인 데이터패스

  • 각 파이프라인 레지스터는 IF, ID, EX, MEM, WB의 파이프라인 stage를 분리하게됩니다.
  • 파이프라이닝을 구현하기 위해서 이전 사이클의 결과를 보관하고 있는 레지스터입니다.
  • 그래서 IF/ID, ID/ED, EX/MEM, MEM/WB 이렇게 4개의 파이프라인 레지스터가 존재하게됩니다.

  • 이에따라

댓글남기기