본문 바로가기
파이프 라인(Pipe Line)의 법칙?

503 파이프 라인(Pipe Line)의 법칙? 뭘 알아야 이해를 하지 사람과 사람의 관계가 깨지면 삶이 고달파 지죠. 이러한 관계가 깨지지 않게 서로서로를 이해하며 살아야 한답니다. 사람은 대화를 통해서 서로를 이해할 수가 있는 존재이지만 ARM core는 대화를 할 수 없으니 개발자가 알아서 관계가 깨지지 않도록 해 줘야 한답니다. 무슨 말인고 하니...ARM core는 메모리에 있는 코드를 읽어오고, 해석하고, 실행 한답니다. 흔히, Fetch – Decode - Execute 라고 표현을 하죠. 이러한 단계가 연속적으로 흘러가게 하면 ARM core의 성능이 아주 좋아진다는 얘기죠. 3개의 단계가 왜 필요할까요?개발자가 C 언어로 개발한 프로그램은 어디에다 넣게 되나요? Flash 메모리죠. 맞습니다. Flash 메모리에 올리게 되죠. 이 Flash 메모리에 있는 데이타를 ARM core가 처리하기 위해서는 메모리에 접근해서 읽어와야겠죠. 그래서 Fetch 단계가 필요하구요, 메모리 접근해서 읽어온 데이타는 ARM core가 이해하는 언어인 기계어로 번역을 해야겠죠. 그래서 Decode 단계가 필요하구요. ARM core가 이해하는 기계어로 번역 후 실행을 해 줘야겠죠. 그래서 Execute 단계가 있는 거랍니다.자 그럼 위에서 설명한 3 단계가 각 단계별로CPU clock을 한 cycle을 소모한다고 가정할게요. 이제 3개의 어셈블리 명령어가 수행한다고 하면 총 몇 cycle이 필요하죠? ... 총 9 번 cycle ①이 필요합니다. 여기서 각 단계별로 사용되는 자원이 다르니 중첩해서 사용해 보자고 생각한 것이 파이프 라인(Pipeline)이에요. 파이프 라인②을 구성하여 시스템을 동작시키면 3개의 명령어를 처리하는데 5 cycle로 동일한 결과를 얻을 수 있게 되요. 그래서 성능이 훨씬 좋아지게 되는 거죠.

가장 기본이 되는 3단계가 있고, 조금 더 세부적으로 나눈다면 5단계, 8단계, 13단계가 있답니다. 3단계만 있으면 되지 않을까 하는 생각도 하시겠지만 조금 더 빠른 처리속도를 내기 위해서는 변화가 필요하답니다. 그래서 ARM7은 3단계, ARM9은 5단계, ARM11은 8단계, CortexA8는 13단계랍니다. 파이프 라인의 구조는 ARM core 내부를 들여다 보면 알 수 있는데, 아래의 그림은 ARM9 core랍니다.

가장 기본이 되는 3단계부터 차근차근 보도록 하죠. ARM7 Core 3단계이며 Fetch – Decode - Execute 랍니다.

파이프 라인 동작 과정을 분석해 보죠.전체 10 cycle 중에 명령어가 실행(Execute)된 것은 8번이네요. 3번째 cycle에서 실행을 시작했답니다. 하드웨어 디버거를 통해 다시 살펴보면 메모리에 있는 코드를 읽어 와서 ①, 디코딩 ② 작업이 끝나면 ARM core의 기계어를 볼 수가 있답니다. 기계어로 된 ARM 명령어를 실행하면 ARM core가 동작을 한답니다. 32bit ARM 명령어라면 주소 증가는 4byte씩 이랍니다.

ARM 명령어 중에 LDR 명령어가 사용이 된다면 파이프 라인 동작단계는 조금 달라진답니다. LDR 명령어는 메모리에 접근하는 명령어랍니다. ARM core는 레지스터/레지스터 명령어와 레지스터/메모리 명령어로 크게 두 가지 명령어군으로 구성되어 있답니다.레지스터/레지스터 명령어레지스터/메모리 명령어명령어 mov r1,r0 add r2,r1,#0x1 sub r0,r1,#0x1 ... ldr r3,0x4CC str r3,0x4CC ....비고mov 명령어가 실행될 때는 단지 R1, R0 레지스터만 있으면 된답니다. add 명령어가 실행될 때는 단지 R2, R1만 레지스터만 있으면 된답니다.ldr 명령어가 실행될 때는 R3 레지스터와 0x4CC인 메모리의 주소가 필요 합니다.레지스터와 레지스터 명령어①는 ARM Core내에서 동작하기 때문에 실행속도가 매우 빠른 반면에 레지스터와 메모리②간의 명령어는 외부 버스를 통해 접근하기 때문에 상대적으로 속도가 느리고, 더불어 파이프 라인 단계도 추가가 된답니다.

ARM7 같은 경우에는 메모리에서 데이타를 읽는 Memory stage①와 레지스터에 쓰기를 하는 Write stage②가 추가가 된답니다. 하지만 ARM7에는 3단계 밖에 없기 때문에 이러한 단계에서는 모두 Stall ③ 된답니다.

이렇게 된다면, 총 10 cycle 동안 명령어 실행(Execute)은 6번만 하게 되죠.ARM9 CoreARM9 core 파이프 라인의 구조를 살펴보아요. ARM9은 5단계로 Memory와 Write 단계가 추가가 됐어요.

ARM7과 LDR 명령어를 비교해 보죠.

Stall 발생하지 않고 동작을 하는 것을 알 수가 있지요. 파이프 라인 공부하시는 분들이 하드웨어 디버거를 이용해서 파이프 라인을 분석하실 때 많이 헷갈린다고 이야기를 하시는데, 왜 그럴까요? 한 번 살펴볼까요?하드웨어 디버거를 이용하여 0x209C ① 주소에서 Breakpoint 걸고 나서 Core를 Running하면 0x209C에 멈추게 된답니다. 멈추게 됐을 때 0x209C는 Fetch/Decode/Execute 중 어느 단계에 해당 될까요? 우선 현재 PC의 이전 주소인 0x2098 주소를 보죠. 0x2098 ② 주소에 MOV 명령어가 있고, 이 명령어는 R0 레지스터에 0x3 넣는 것인데, 현재 레지스터 값을 보니 이미 0x3이라는 값이 들어가 있군요. 어라? 이건 무슨 시츄에이션...그렇다면 분명 0x2098은 Execute 단계라는 결론과 함께 0x209C 는 Decode ③ 단계라는 이야기가 되는 군요. 맞나요? 정말요? Really? 아닙니다요. PC는 항상 Fetch를 가르쳐야 되는 거잖아요. 그럼 왜 틀렸는지 설명 드리죠.하드웨어 디버거는 여러 종류의 디버거가 있는데, 임베디드 시스템에서 가장 많이 사용하는 하드웨어 디버거가 바로 JTAG 기반을 둔 툴이랍니다. 이 툴들은 Real-time성이 깨진다는 특징을 가지고 있답니다. 무슨 말인고 하니, JTAG 기반의 툴들을 이용했을 때 실제 파이프 라인을 고려해서 디버깅 해 주는 것이 아니라 파이프 라인을 무시하고 디버깅을 해 준답니다. 결론은, 이론적으로는 0x209C가 Decode가 되어야 하지만 하드웨어 디버거를 사용한다면 파이프 라인이 무시되고 Fetch-Decode-Execute가 한꺼번에 실행 된답니다. 0x209C 주소에 멈추어 있을 때 0x2098 주소에 있는 코드는 Execute가 끝난 상태이고, 0x209C는 다시 Fetch-Decode-Execute 단계를 한꺼번에 실행할 준비를 하고 있는 상태랍니다.

멈추고 난 후 하드웨어 디버거에서 Step 같은 명령을 내리면 0x209C 주소의 명령어가 실행 준비를 하는데, 이때 Fetch-Decode-Execute 단계를 한꺼번에 처리하면서 ARM core가 동작된답니다.그런데, 파이프 라인을 정확히 지켜 주는 때가 있답니다. 바로 변수에 Write breakpoint를 설정한 경우랍니다. 이 부분은 "508 하드웨어 디버거와 Breakpoint" 에서 자세히 다루어 보도록 할게요. ARM11 Core이제부터 파이프 라인은 아주 복잡해 진답니다.파이프 라인은 Fetch stage 2단, Decode Stage, Issue Stage, Execute Stage 4단으로 총 8단계로 구성되어 있답니다.

Execute 단계는 4단계로 되어 있는데, 각 명령어 처리 unit 이 분리 되어 있답니다. 산술/논리 연산 처리는 ALU pipeline 단계에서 처리를 하며, SH - ALU - SAT 단계에서 담당한답니다. 곱셈 연산 처리는 MAC pipeline 단계에서 처리를 하며, MAC1-MAC2-MAC3 단계에서 담당한답니다. Load 명령과 Store 명령 처리 전용은 Load/Store pipeline 단계에서 처리하며, ADD-DC1-DC2에서 담당한답니다.ARM11에서는 pipeline 효율을 높이기 위한 Program Flow Prediction 기능이 있답니다. 명령의 흐름을 예측하여 pipeline의 stall 현상을 줄여 효율성을 높여 주는 역할이랍니다. Dynamic branch prediction, Static branch prediction, Branch folding, Return stack 들이 그 역할들을 하죠. ARM1176JZF-S 프로세서 구조를 보면서 Program Flow Prediction 살펴 보죠.Prefetch Unit ①에 Dynamic Branch prediction, Branch folding 포함되어 있어요. 그리고 Integer core ②에는 Static branch prediction, Return stack 들어 있답니다.

Dynamic branch prediction는 과거 기록을 사용해서 똑 같은 분기가 이전에 있었는지 없었는지, 실행되는 횟수가 많을지, 실행되지 않는 횟수가 많을지를 조사한답니다. 이것은 BTAC(Branch Target Address Cache)에 의해 이루어진답니다. Branch명령의 주소는 BTAC의 entry정보와 맞을 경우 이곳에서 명령어를 fetch한답니다. Co-processor의 CR(Control Register) 레지스터 Z[11]bit을 조절하면 Program Flow Prediction을 Enable/Disable을 설정할 수가 있답니다. 만약 Z bit가 enable이 됐다면, 다시 ACR(Auxiliary Control Register) 레지스터에 의해 static branch prediction, dynamic branch prediction, return stack, Branch folding 설정할 수가 있답니다. 소스 코드를 보면 다음과 같아요.먼저 Program flow prediction enabled 해 주셔야 합니다. ▶코드 mmu.s MRC p15,0,r0,c1,c0,0 ; Read Control Register configuration data ORR r0, r0, #0x800 ; 1 = Program flow prediction enabled MCR p15,0,r0,c1,c0,0 ; Write Control Register configuration data 하드웨어 디버거로 Co-processor 레지스터를 확인해 보죠.

이제 ACR레지스터를 이용해서 나머지 prediction을 Enable을 해 보도록 하죠. ▶코드 mmu.s MRC p15,0,r0,c1,c0,1 ; Read Auxiliary Control Register ORR r0, r0, #0x4 ; 1 = Static branch prediction is enabled SB-bit[2] ORR r0, r0, #0x2 ; 1 = Dynamic branch prediction is DB-bit[1]enabled ORR r0, r0, #0x1 ; 1 = Return stack is RS-bit[0]enabled MCR p15,0,r0,c1,c0,1 ; Write Auxiliary Control Register Return stack 은 R14 링크 레지스터 값과 호출 함수의 ARM/THUMB 상태를 저장하는 32bit 항목을 8개 가지고 있고, return 타입 명령이 받아들여진 것으로 예측되면 Return stack은 마지막으로 더해진 주소와 상태를 제공 한답니다. ▶코드 mmu.s MRC p15,0,r0,c1,c0,1 ; Read Auxiliary Control Register BIC r0, r0, #0x20000000 ; 0 = Branch folding is enabled, ; when branch prediction is enabled, reset value MCR p15,0,r0,c1,c0,1 ; Write Auxiliary Control Register 하드웨어 디버거 장비를 확인을 해 보면 다음과 같아요.

ARM9 core - "500" Co-processor – “201”

Linked at 친절한 임베디드 시스템 개발자.. at 2012/03/21 23:52

... 누구냐? 502 R13, R14에게 반했다? 503 파이프 라인(Pipe Line)의 법칙? 504 스케터(scatter) 파일은 어떻게 만들죠? 5 ... more

Commented by 김광택 at 2012/03/22 14:55
흥미롭군요!
Commented by 감사합니다 at 2012/03/22 18:48
그림에 WRITE인데 WHITE라고... typo인것 같아요.
글 감사합니다.
Commented by soto at 2012/03/23 04:40
관심있게 봐 주셔서 감사합니다.
그리고, 그림 오타...
지적 감사합니다.
Commented by 히언 at 2012/03/22 19:21
으흠~ Soto님 화이팅.
Commented by 감사합니다 at 2012/03/23 15:45
학교에서 공부한 내용이 현업에서 어떻게 쓰이나요?
거기도 PETCH->FETCH 이것도 typo인것 같아요.
원문에 댓글을 못달아 여기에 남겨요.
글 감사합니다.
Commented by soto at 2012/03/25 08:11
거기에도 숨은 그림이 있었군요..
감사합니당~~~ㅎㅎ
Commented at 2012/03/30 02:27
비공개 덧글입니다.
Commented by 히언 at 2012/03/30 12:07
ㅎㅎ Soto님의 강좌도 책으로 나와 있어요.
http://www.cornerbook.co.kr/shop/goods/goods_view.php?goodsno=186785450&category=
임베디드 스케치고요.
Soto님~ 답변 부탁해요~
Commented by soto at 2012/03/30 13:20
질문 감사합니다.


공모전이라면,
우선 개발 툴을 모두 가지고 있으신가요?
개발 보드는요?
모든 것을 만족 시키며 공모전에 나가는 것은 시간 제약으로 인해 다소 어려워 보이네요.
뭐든지 짧은 시간에 뭔가를 해야 한다면 , 수학 공식 외워 공부하듯이 이번 프로젝트도 그렇게 진행 해 보면 어떨까요?


단계별 공식
1. 임베디드 개발 보드 확보
2. 개발툴 확보
3. 개발 보드 메뉴얼 대로 RTOS 또는 application 포팅
4. 공모전을 위한 application 개발


그런데, 이 과정은 단순히 공모전을 위한 것이지 개인의 스킬 향상에서 그리 많은 도움이 되지 않을 것 같아요.
취업을 목적으로 해서 정말 제대로 된 공부를 하시려면 차근차근 해 보는것도 좋을 것 같네요.


아래 글 읽어 보세요. 모든걸 할 수 없으니 한가지에 집중해 보세요.


http://recipes.egloos.com/5220643


감사합니다.
※ 이 포스트는 더 이상 덧글을 남길 수 없습니다.
친절한 임베디드 시스템 개발자 되기 강좌 글 전체 리스트 (링크) -



댓글





친절한 임베디드 개발자 되기 강좌 글 전체 리스트 (링크) -