05 ILP (1)

초강송·2026년 4월 10일

고급컴퓨터구조

목록 보기
4/11

05 ILP (1)

Clock cycles

  • cpu 안에는 수많은 회로가 존재하고, 회로 간 sync를 맞추기 위해 clock이 존재
  • clock period = time between clock ticks = clock rate(freqeuncy) = 초당 돌릴 수 있는 cycle 수
  • single-cycle machine
    • 1 instr = 1 cycle
    • fetch→decode→execute→memory→write-back 전부 한 cycle에 처리
    • low clock frequency
    • high hardware cost
  • multi-cycle machine
    • instruction broken into multiple cycles/stage
    • fetch(1 cycle)→decode(2 cycles) …
    • high clock frequency
    • reuse expensive hardware across multiple cycles
      • hw를 reuse 한다는 건, 여러 clock에 걸쳐 hw를 다시 쓴다는 걸 의미
    • clock cycle이 끝날 때마다 intermediate result를 저장해야 함 → hardware overhead
    • 한 cycle에 한 stage만 실행, cpu의 전체 resource를 충분히 활용 X → some hardware resources are idle (e.g. datapath는 mem access 동안 idle) → limited concurrency

Pipelining

  • More concurrency → higher instruction throughput
    • 한 cycle에 처리 가능한 instr 개수를 늘리자 ⇒ IPC 를 높이자
  • ideal pipeline
    • repetition of identical operations (e.g. 세제 → 헹굼 → 탈수)
    • repetition of independent operations (e.g. bypass가 필요 x)
    • uniformly partitionable subperations (e.g. 각 단계가 비슷한 latency를 가져야 함)

Data dependency

  • Flow dependence (true data dependence, Read After Write)

    • forwarding (bypassing)
    • reorder code
  • Anti dependence (Write After Read)

  • Output dependence (Wrtie After Write)

  • Anti랑 Output은 진짜 value에 대한 dependence가 있다 이것보단 name에 대한 dependence가 있다고 표현함 → register 수가 부족해서 발생하는 dependence

Precise exception

  • 예외가 발생했을 때, 이전 명령어는 모두 완료(retire) 되고, 이후 명령어는 하나도 retire 되지 않은 상태로 유지할 수 있어야 함 → os나 예외 처리 루틴이 그 시점의 상태를 정확히 디버깅하고, 복원할 수 있도록
  • multi-cycle 구조에서 pipelining을 적용하면 나중 명령어가 이전 명령어보다 빨리 끝날 수 있음 → 예를 들어 MUL → ADD 순서일 때 ADD가 먼저 끝날 수 있음 → 명령어 실행 순서가 ISA에서 정의한 sequential semantics와 달라짐 → exception이나 interrupt 발생 시 hard to debug
  • 모든 instr이 같은 execution time을 갖게 하자 → worst-case instruction latency가 곧 모든 instruction의 latency가 됨

ROB (ReOrder Buffer)

  • cpu 안에 있는 FIFO 구조의 circular queue, HW
  • instr은 out-of-order로 실행하되, 결과는 in-order로 commit (ROB 도입 이후에는 꼭 MUL→ADD 순서가 아니라 ADD가 MUL보다 먼저 실행될 수 있음)
  • instr은 decode 단계에서 ROB entry를 예약함
  • execution이 끝나면 결과값을 register file에 직접 쓰지 않고, ROB entry에 저장함.
  • commit 시점에서는 ROB의 head가 가리키는 entry부터 확인하며 retire시 → instr이 정상적으로 완료되었고, 예외가 없으면, 그 결과를 register file에 반영

  • instruction이 필요로 하는 register 값은 시점에 따라
    • 방금 계산된 결과를 forwarding으로 받을 수도 있고,
    • ROB에서 commit 되지 않은 값을 읽을 수도 있고,
    • commit이 완료된 값을 register file에서 읽을 수도 있음
  • 위 구조 덕분에, cpu는 data dependence로 인한 stall을 줄이고 out-of-order 실행 중에도 정확한 data flow를 유지할 수 있음

  • 이전의 ROB는 content-addressable 방식이라, register ID(content of array) 가지고 ROB를 일일이 다 찾아봐야 하는 문제가 있음

    → HW cost가 너무 크고, 너무 느림

    → register file에 TAG를 둬서, 이 register의 최신 값이 ROB의 어디에 있는지도 알려주자

    → register file의 valid bit 가 0이라면, TAG에 최신 값이 저장된 ROB entry ID를 저장해둠

    → ROB를 더 이상 content-addressable이 아닌 인덱스로 접근 가능한 random access 구조로 바꿈

    → TAG를 덮어써서 최신 값 위치를 계속 수정할 수도 있음

  • Anti, Output dependence는 레지스터 수가 부족해서 발생하는 dependence이므로, ROB+TAG (즉 register renaming)을 쓰면, 마치 많은 레지스터가 있는 것처럼 동작해서 이러한 의존성을 제거할 수 있음

  • ROB를 사용하는 구조는 precise exeption을 구현하기 쉬움

    → ROB가 모든 instr 결과를 in order로 관리하기 때문에 예외가 발생하면 뒷 entry는 commit 안 하면 돼

  • Anti, Output dependence 제거 가능

  • ROB를 사용하면, 아직 register file에 commit 되지 않은 결과값을 가져오기 위해, ROB에 직접 접근해야 하는 추가 단계(indirection이라 표현)가 필요

    → 그 전에는 register만 확인했는데, invalid의 경우 ROB까지 확인해야 하므로 latency, complexity 증가

Out-Of-Order

  • dispatch는 decode 이후에 실행되는 단계로, instr을 reservatoin station으로 보내는 단계임. → reservatoin station에 있다가, operand가 준비되면 issue 되어서 execute
  • in-order dispatch의 경우, 앞 명령어에 의존성이 있는 뒤 명령어가 원하는 레지스터가 준비될 때까지 stall → 뒤쪽의 독립적인 다른 instr들도 같이 멈춰 → 한 instr이 전체 pipeline을 막는 상황이 발생
  • 준비되지 않은 instr은 옆으로 치워 두고, 준비된 instr 먼저 실행하자 → inst 실행 순서가, program(control) order가 아니라 데이터가 준비된 순서(dataflow order)로 바뀜

Compiler vs H/W

compile-time instruction scheduling

  • 실행 전, 컴파일 전에 컴파일러가 미리 instr 순서를 재배치하는 방식
  • static한 판단 → 실제 실행 시점의 메모리 delay나 분기 결과 같은 건 알 수 없음
  • 컴파일러(소프트웨어)가 하는 일이라 hw cost는 적지만 runtime variation은 반영 X

out-of-order execution

  • 런타임에 HW가 직접 이 instr은 operand가 준비됐으니 먼저 실행하자 식으로 스케줄링
  • 캐시 미스, 분기 결과 등 runtime variation에 대응 가능함 → ILP를 극대화할 수 있음
  • 전적으로 HW가 판단하고 관리하기 때문에 co큼

0개의 댓글