ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 0x00.파이프라인(Pipeline)
    0x.Pwnable 2017. 2. 26. 18:33

    파이프라인(Pipeline)

     


     

    명령어 파이프라인(instruction pipeline)은 명령어를 읽어 순차적으로 실행하는 프로세서에 적용되는 기술로, 한 번에 하나의 명령어만 실행하는 것이 아니라 하나의 명령어가 실행되는 도중에 다른 명령어 실행을 시작하는 식으로 동시에 여러 개의 명령어를 실행하는 기법이다.


    파이프라인을 가끔, 한 제품을 만들때 여러 개의 제품이 동시에 조립공정되는 과정에 비유하기도 한다.

     

    하나의 명령어는 여러 개의 단계로 나눌 수 있는데, 이때 하나의 명령어를 처리할 때까지 다음 명령어가 처리되지 않고 기다리게 된다면, 명령어의 특정 단계를 처리하는 동안 다른 단계를 처리하는 부분은 아무 작업도 하지 않게 된다. 이때 파이프라인을 사용하면 한 명령어의 특정 단계를 처리하는 동안 다른 부분에서는 다른 명령어의 다른 단계를 처리할 수가 있게 되므로 속도가 향상될 수 있다.

     


    명령어 처리 사이클


    ① Instruction Fetch(IF)

    명령어를 읽어 프로세서 내의 명령어 해석기로 가져온다.

     Instruction Decode(ID)

    명령어 해독 및 레지스터 파일 읽어온다.

     Execute(EX)

    실행(ALU) 또는 주소를 계산해준다.

     Memory Access

    데이터 메모리에 있는 데이터에 접근한다.

     Write Back(WB)

     데이터값 또는 결과값을 레지스터에 쓴다.

     

     


     

    다음의 그림과 같이 여러개의 명령어가 동시에 실행시키는 기법이 파이프라인이다.

     


    파이프라인 해저드(Hazard)

    파이프라인은 여러가지 명령어를 동시에 실행시키기 때문에 여러가지 위험요소가 있다. 파이프라인 해저드란 다음사이클의 명령어를 실행하지 못하는 경우나 파이프라인의 속도가 느려지는 경우를 일컫는다.

     

     

    1) 구조적 해저드(Structural Hazard)

    만약 하드웨어가 동시에 실행되는 모든 명령어들을 수행할 수 없을 시 발생되는 위험이다. 다시 말해, 두 개 이상의 명령어가 동시에 같은 메모리 소스에 접근할 때 발생하는 위험이다(충돌). A라는 명령어가 실행이나 쓰기를 위해 메모리에 접근하는데, B라는 메모리가 메모리에서 정보를 읽어오는 경우와 같이 말이다. 쉽게 예를 들자면, 사람이 넥타이를 매는 것과 푸는 것을 동시에 하는 것과 비슷하다고 생각하면 된다.

     

     

     

     

    보통 구조적 해저드는 버블(bubble)을 이용해 해소시키는데, 여기서 버블이란 아무 것도 수행하지는 않지만 시간을 벌어주는 역할을 한다. 버블을 통해 Stall을 하게되면 조금의 시간을 벌어주어서 클록 사이클에서 두 명령어가 겹치는 경우를 피할 수 있다.

     

     

     

     

    2) 데이터 해저드(Data Hazard)

    데이터 해저드는 현재 수행해야할 명령어가 이전의 명령어에 종속되어 있을 때 발생한다. 예를 들어, 나눗셈 연산을 처리 중일 때 그 다음 명령어는 처리할 수 있는 연산자가 없어 실행이 연기되는 것과 같은 경우이다.

     

    Read After Write(RAW) : 명령어가 쓰이기 전에 불러오려고 할 때 발생됨 (Dependence)

    eg) add r1. r2. r3

          sub r4, r1, r3

    Write After Read(WAR) : 명령어를 불러오기 전에 쓰려고 할 때 발생됨 (Anti-Dependence)

    eg) sub r4, r1, r3

          add r1, r2, r3

    Write After Write(WAW) : 명령어가 쓰이기 전에 쓰려고 할 때 발생됨 (Output dependence)

    eg) sub r1, r4, r3

          add r1. r2. r3

     

    데이터 해저드일 경우 포워딩(Forwarding)을 통해 해결한다.

     

      

    포워딩은 ALU로 부터 나온 값을 버스에서 MUX로 연결해서 해당 레지스터 값을 선택할 수 있도록 해주는 것이다. 즉, 모든 절차가 끝나기를 기다리기 전에 ALU에서 계산된 데이터를 별도의 바이패스 구조를 통해 가져와 사용한다는 것이다. 이 과정을 통해 MEM, REG를 거치지 않은 상태에서 필요한 데이터를 넘겨줄 수 있기 때문에 사이클을 줄일 수 있다. 

     

    하지만 포워딩을 사용해도 데이터 해저드가 발생할 수 있는데 이 경우에는 소프트웨어의 스케쥴링(Software Scheduling)을 통해 조절을 해야한다. 버블등을 사용해서 말이다.

     

     

    3) 컨트롤 해저드(Control Hazard)

    컨트롤 해저드는 명령어 해저드라고 부르기도 하는데, 보통 프로그램 카운터(PC)의 값이 브랜치(branch)로 인해 변경되었을 때 발생한다.

     

    ※ Branch : 분기

     

     

     

     

    그림을 보면, T2 사이클에서 PC의 값이 필요하지만 첫번째 파이프라인의 MEM과정을 수행해야지만 얻을 수 있다. 이 문제를 해결하기 위해서는 명령어를 다시 읽어와야한다(re-fetch).

     


     

    다음과 같이 버블을 통해 IF 명령을 첫 번째 파이프라인의 MEM 명령뒤에 수행되도록 위치해주면 해결할 수 있다. 즉, 사이클에서 소요될 시간을 예측해주는 것이다. 

     

    이러한 방법들은 사이클을 손해볼 수 있는데, 줄이기 위해 지연 슬롯(Delay Slot)을 사용한다.

     

     

    다음의 그림과 같이 delay slot을 사용하게 되는 경우를 살펴보면, if문의 조건을 검사하는 동안, 조건/분기문과 연관이 없는 명령어를 수행함으로써, 사이클을 효과적으로 줄일수 있다.

     

     

    해저드를 해결하는 가장 좋은 방식은 해저드의 원인이 사라질 때까지 스톨(stall)하는 방법이다.




    '0x.Pwnable' 카테고리의 다른 글

    0x03.Browser Exploit Reference  (0) 2019.02.22
    0x02.Local Privilege Escalation(LPE)  (0) 2019.02.13
    0x01.버퍼 오버플로우(Buffer Overflow)  (0) 2017.07.07

    댓글

Designed by Tistory.