컴퓨터(Computer Science)/컴퓨터구조(Computer Arichitecture)

Parallelism, 병렬구조 [컴퓨터구조]

게임이 더 좋아 2021. 6. 20. 04:44
반응형
728x170

 

일반적으로는 Instruction을 한 싸이클에 하나씩 실행한다고 했지만

Pipeline으로 각 구간을 나누어 구간마다 사용하게 했다.

 

또 마지막으로는 현재는 성능을 위해서

한 사이클에 여러 개의 Instruction을 실행한다고 했다.

 

즉, 병렬이 차차 나오기 시작했다.

 

한 번 알아보자

 


 

 

Pipelining 자체도 병렬화라고 볼 수 있다.

 

그래서 병렬의 성능을 이끌어내려면 어떡해야지?

 

기본적으로 파이프라인의 단계를 늘리는 것이다.

이전의 식과 마찬가지로 n이 무한대로 늘어난다면 성능 향상은 거의 stage의 수에 가까워진다고 했다.

 

또는 한 번에 여러개를 실행하는 것이다.

이것이 바로 한 싸이클에 여러 개의 Instruction을 수행하는 것이다.

 

즉, 파이프라인 여러 개를 만들어서 수행하는 것이다.

이렇게 하는 경우 CPI가 1보다 작아진다. -> 분모가 커지니까

그래서 현재 우리가 많이 쓰는 CPU는 성능을 IPC로 바꿔서 쓴다.

한 싸이클에 Instruction이 얼마나 실행되는지가 성능의 척도가 되었다.

 

즉, 우리 시대에서는 파이프라인이 여러 개인 CPU를 쓰고 있다고 볼 수도 있다는 것이다.

 


 

그렇게 여러 개의 파이프라인을 형성한다면..?

어떤 방법으로?? 어떤 순서로..? 어떻게 해저드를 피하고 그러는거지??

 

 

우리는 2가지 방식으로 구현한다.

 

Static 같은 경우

컴파일러가 해저드를 발견하고 알아서 피하게끔 Instruction이 실행되도록 정한다.

컴파일러가 명령어들을 grouping하고 묶어서 관리한다.

Static인 만큼 컴파일 타임에 한다.

 

 

Dynamic의 경우

CPU, 프로세서가 한다.

프로세서가 직접 Instruction들을 보고 각 사이클에 무엇을 실행할지 정한다.

물론 컴파일러도 CPU를 보조할 수 있다.

하지만 Static과는 다르게 해저드를 발견하고 피하는 것은 CPU의 몫이라는 점이다.

또한 Dynamic인 만큼 Runtime에 실행된다.

 


 

또한 이 과정에도 Prediction과 비슷한 과정이 있다.

Speculation이다.

 

 

명령어가 무엇을 할 지 추측하는 것이다.

명령어를 최대한 빨리 수행시작한 다음

추측이 맞으면 빨리 실행되는 것이고

아니면 롤백한다음 다시 올바르게 수행한다.

 

이러한 기법은 Static, Dynamic Multiple 작업에 둘 다 활용되고 있다.

 

대표적인 예는

Branch speculation과 load speculation이 있다.

branch prediction과 같다고 보면 된다.

load는 그 값이 올 것같다고 미리 불러 놓은 다음에 실행하는 것을 말한다.

 


 

Speculation 하는 주체가 2개가 있다

하드웨어(CPU)와 컴파일러다.

 

 

파일러가 미리 작업할 명령들을 재배치하거나

하드웨어는 버퍼를 이용하여 실행될 것 같은 데이터들을 가지고 있고

쓰이지 않으면 flush 하는 방식으로 speculation을 한다.

 


 

더 복잡한 경우도 있다.

speculation과정에서 exception이 생기면 어떡하나?

이런 것까지 고려해줘야 한다.

 

 

Static에서는

Exception 발생을 뒤로 미룰 수 있다(deffering)

-> speculation말고 실제로 그 Exception이 나올 때까지

 

Dynamic에서는

실제 명령이 끝날 때까지 Exception을 버퍼에 넣어놓는다.

 


 

해당 Static 방법에 대해 더 자세하게 알아보자.

 

 

아까도 말했듯이

컴파일 타임에 컴파일러가 instruction들을 그루핑하는데 그것을  issue packets 이라고 한다.

그 명령어 그룹들을 한 사이클에 실행하는 것이다.

즉, 컴퓨터 구조에 맞는 컴파일러를 사용해야 제 성능을 발휘할 수 있다.

 

그런 이슈 issue packets을 여러개 만드는 것보다 그 자체를 엄청나게 길게 만들어 버리는 것이다.

VLIW방식이라고 말한다.

Static은 위 방식을 일반적으로 수행한다.

 

즉, 위의 방식을 실행하게 하려면 특히 해저드를 막아야 한다.

컴파일러를 잘 만들어야

issue packets을 만들고 재정렬 할 때 해저드가 발생하지 않는다.

 

또한 같은 패킷 안에서는 dependency가 발생하지 않게 한다.

(패킷 간에는 dependency 있을 수 있음)

 

예를 들면

 

한 번에 2개의 Packet에 대해서 수행하는 것이다.

 

Datapath 는 참고하자

Instruction Memory가 2개씩 fetch 되는 것을 볼 수 있다.

보면 새로운 Resource 추가가 그렇게 많이 없다.

 

하지만 역시나 해저드는 존재한다.

 

 

데이터 해저드 같은 경우 포워드로 해결이 가능했지만

같은 패킷 안에

ALU 결괏값 과 load 의 레지스터 번호가 겹쳐버리는 경우가 발생한다면

어쩔 수 없이 stall이 발생해버린다.

 

Load-Use 해저드 또한 마찬가지이다.

그래서 Scheduling을 잘해야한다는 것이다.

 

예를 들면

 

 

Dependency가 있다면 같은 싸이클에 실행할 수가 없다.

 

그래서 실제로 2개가 한 사이클에 실행되지만

한 개만 실행되는 경우가 발생하는 것이다.

그래도 실제로 5번에 걸쳐서 5개의 instruction에 수행되는 것보다 빠르다는 것을 알 수 있다.

 

 


 

이번엔 Dynamic 에 대해서 알아보자

 

 

얘는 따로 이름이 있다.

Superscalar 라고 부른다.

 

CPU가 특정한 사이클에 실행될 명령어를 골라내는 것이다.

CPU가 해저드를 피하게끔 하는 것이다.

또한 CPU가 임의대로 골라서 실행하더라도 결과가 같음이 보장되게 해야한다.

 

바로 보자

 

CPU가 실행 순서를 정하지만

실제로 레지스터에 결과를 쓰는 것은 순서대로 해야한다. 

 

실행은 CPU임의대로 하지만 쓰기는 순서대로 해야한다는 말이다.

 

 

 

Reservation은 버퍼라고 생각하자

Reservation에 필요한 데이터가 다 있으면 Functional units에서 바로 연산을 진행하고 그렇지 않으면 기다린다.

 

즉, Instruction Fetch와 commit은 In-order

Execution은 Out-of-order

 

 

또한 reservation에서 대기하고 있는 값의 경우

레지스터가 값을 가지고 있는데

대기 중이고 다른 Functional unit에서 레지스터가 필요한 경우 overwrite해서 레지스터를 쓸 수 있다.

 

Speculation은 역시 앞서 말했지만

다 아는 내용이다.

 

 

여기서 중요한 것은

load는 speculation이 다 맞았거나 틀려서 롤백한 다음 맞은 결과가 나올 때 까지 진행하면 안된다는 말이다.

확실해지기 전까지는 하지 마라 이말이다.

 

 

분명 Static도 좋아보였지만

Dynamic을 쓰는 것이 대부분이다. 

 

 

 

컴파일러 수준에서는 모든 stall을 예측하기 힘들기도하고

branch 같은 경우는 동적으로 결괏값이 나오기 때문에 스케줄하기 힘들고

컴파일러 성능이 latency와 hazard를 다 고려하기 힘들기 때문이다.

 

 


 

이론적으로는 병렬실행하는 것이 좋구나 알아봤지만

실제로도 잘 될까??

 

 

잘 된다. 하지만 기대한만큼은 아니다.

2개를 돌린다고해서 2배 빨라지는 것도 아니다.

dependency가 크게 작용하기 때문이다.

병렬구조 자체가 구성하기 힘들고

메모리 지연과 제한된 대역폭으로 실제로 파이프라인을 계속 작동시키기가 어렵다.

Speculation을 하면 그래도 성능에 도움이 되더라.

 

이론적으로는 쉬워보이지만 엄청나게 어려운 영역이 여기다.

그래서 회로 설계하는 사람들이 돈을 많이 받는다.

 

결론은 이렇다.

 

 

ISA와 Design of Datapath는 서로 영향을 주고 받는다.Pipeline은 응답시간보다 Throughput 향상이다.IPC를 사용한다.해저드 종류는 3가지다.

Multiple issue는 Power wall issue와 연결되어있다.

 

 

 

반응형
그리드형