목록CS/컴퓨터 구조 (13)
보근은 참고 있다
오류: 강력한 명령어를 사용하면 성능이 좋아진다. intel x86 명령어는 접두사를 이용해 명령어 실행 방식을 변경할 수 있기 때문에 매우 강력하다. 그중 한 접두사는 카운터 값이 0이 될 때까지 명령어 반복 실행이 가능하게 해준다. 그러나, 순환문 오버헤드가 없도록 명령어를 반복적으로 늘어놓는 방법을 쓰면 접두사를 쓴 것보다 약 1.5배 빠르다. 오류: 최고 성능을 얻기 위해 어셈블리 언어로 프로그램 작성하기. 과거에는 컴파일러가 출력하는 코드의 성능이 좋지 못했으나, 현재는 컴파일러 기술이 발달하면서 컴파일한 코드와 직접 손으로 작성한 코드의 차이가 급격히 줄어들었다. 상위 수준 언어로 프로그램을 작성해 컴파일하는 이유는 다음과 같다. 컴파일러 기술이 발달된 지금, 어셈블리 프로그래머가 컴파일러의 ..
이 절에서는 두 가지 C 프로시저의 MIPS 코드를 만들어 본다. 하나는 배열 원소 두 개를 맞바꾸는 것, 다른 하나는 배열 원소를 정렬하는 것이다. C 프로그램을 어셈블리 프로그램으로 바꿀 때는 다음 절차에 따라 번역한다. 1. 프로그램 변수에 레지스터를 할당한다. 2. 프로시저 본체에 해당하는 코드를 생성한다. 3. 프로시저 호출 후의 레지스터 내용을 호출 전과 같도록 만든다. 프로시저 swap void swap (int v[], int k) { int temp; temp = v[k]; v[k] = v[k+1]; v[k+1] = temp; } 레지스터 할당 인수 v, k를 각각 $a0와 $a1에 할당한다. 그 외의 변수는 temp 뿐인데 swap은 말단 프로시저이므로 레지스터 $t0에 할당된다. 본체..
컴파일러 컴파일러는 상위 수준 프로그램을 어셈블리 언어 코드로 바꾼다. 어셈블리 언어 프로그램은 컴퓨터가 이해할 수 있는 심벌 형태이다. 어셈블리 언어 프로그램에 비하면 상위 수준 프로그램의 문장 수는 훨씬 적다. 결국, 이 과정은 프로그래머의 생산성을 높여준다. 어셈블러 어셈블러는 어셈블리 언어 코드를 기계어 형태의 목적 모듈로 바꾼다. 어셈블리 언어는 상위 수준 프로그램과 기계어 사이의 인터페이스 역할을 한다. 이 명령어들은 하드웨어로 구현이 되어 있지 않더라도, 어셈블러가 알아서 처리하여 번역과 프로그래밍을 간편하게 해 준다. 이런 명령어들을 의사명령어(Pseudo instruction)이라 한다. ex) move $t0, $t1 -> add $t0, $zero, $t1 // 기계어 명령어에는 mo..
태스크가 서로 독립적일 때는 병렬처리가 필요가 없지만, 서로 협력해야 하는 경우 매우 중요하다. 협력이란 어떤 태스크들이 읽어야 할 값을 다른 태스크들이 쓰는 것을 의미한다. 그들 사이에 동기화가 되지 않으면 데이터 경쟁관계(data race)의 위험이 있다. 컴퓨팅에 있어서 동기화 메커니즘은 일반적으로는 사용자 수준의 소프트웨어 루틴에서 제공되는데, 이 소프트웨어 루틴들은 하드웨어가 제공하는 동기화 명령을 이용한다. 이 절에서는 lock과 unlock 동기화 연산의 구현에 집중한다. lock과 unlock을 이용하여 단 하나의 프로세서만이 작업할 수 있는 영역(상호배제(mutual exclusion))을 생성하며, 더 복잡한 동기화 메커니즘을 구현할 수 있다. 멀티 프로세서에서 효율적으로 기본 동기화 ..
MIPS의 명령어 길이를 32비트로 고정한 덕에 하드웨어가 간단해졌지만, 32비트짜리 상수나 주소를 사용하면 편한 경우가 많다. MIPS는 32비트 상수나 주소 역시 지원한다. MIPS의 명령어는 상수타입(I타입)을 지원하지만, 16비트가 한계이다. 대부분의 상황에서 16트로 충분하지만 예외의 경우에 더 큰 상수가 필요할 때가 있다. 그런 경우를 위해 MIPS는 lui(Load Upper Immediate) 명령어를 제공한다. lui는 상위 16비트에 상수를 넣고 그 다음에 나오는 다른 명령어로 하위 16비트를 채움으로써 32비트 상수를 사용할 수 있다. ex) $s0에 32비트 상수를 채워라. lui $s0, 320 // $s0 = 0000 0001 0100 0000 0000 0000 0000 0000..
프로시저 프로시저란, 제공되는 인수에 따라서 특정한 작업을 수행하는 서브 루틴. 프로시저는 지정된 작업 외의 다른 것은 아무 것에도 영향을 주어서는 안된다. 프로그램의 프로시저 호출 후 실행 6단계 : 프로시저가 접근할 수 있는 곳에 인수를 넣는다. ($a0~$a3) 프로시저로 제어를 넘긴다. 프로시저가 필요로 하는 메모리 자원을 획득한다. 필요한 작업을 수행한다. 호출한 프로그램이 접근할 수 있는 장소에 결과 값을 넣는다. ($v0~$v1) 프로시저는 프로그램 내의 여러 곳에서 호출될 수 있으므로 원래 위치로 제어를 돌려준다. ($ra) 프로그램 또는 프로시저가 프로시저를 호출 하려면 이동 명령어가 필요하다. MIPS에서는 jal(Jump And Link) 명령어가 있다. jal의 jump는 프로시저로..
컴퓨터가 단순한 계산기와 다른 점은 판단 기능이 있다는 것이다. ----------------------------------------------------------------------------------------------------------------------------------- 판단을 위한 명령어에는 ① beq, ② bne, ③ slt, ④ slti, ⑤ sltu, ⑥ sltiu 들이 있다. ① beq (Branch if EQual), ② bne (Branch if Not Equal) 이 두 명령어들은 두 값이 같은지 다른지 결과에 따라 프로그램 내의 다른 주소로 제어를 넘길 수 있다. 이것을 조건부 분기라고 한다.(if-then-else) ① beq는 두 피연산자를 비교해 같으면 ..
초기의 컴퓨터는 워드 전체를 처리하는 데에만 관심을 가졌으나, 워드 내의 일부 비트들을 처리하는 것에 필요성을 느꼈다. 그로인해 비트들을 워드로 묶는 packing 작업과 워드를 비트 단위로 나누는 unpacking 작업을 하는 명령어들이 생겨났다. ----------------------------------------------------------------------------------------------------------------------------------- MIPS에는 이러한 논리연산 명령어가 7가지가 있는데, ① sll ② srl ③ and ④ or ⑤ not ⑥ nor ⑦ xor 들이다. ① sll (Shift Left Logical) 과 ② srl (Shift Right L..
사람이 컴퓨터에 명령을 내리는 방법과 컴퓨터가 명령어를 해석하는 방법의 차이를 알아보자. 명령어도 컴퓨터 내부에서는 높고 낮은 전기 신호의 연속으로 저장된다. 실제로 명령어의 각 부분을 숫자로 볼 수 있으며, 이 숫자들을 나란히 늘어놓으면 명령어가 된다. 레지스터 역시 명령어에 참조되기 때문에 레지스터 각각을 숫자로 매핑하는 규칙이 있다. $s0 ~ $s7은 16~23, $t0 ~ $t7은 8~15 등등. MIPS 명령어의 길이는 데이터 워드와 마찬가지로 32비트이다. "간단하게 하기 위해서는 규칙적인 것이 좋다"라는 설계 원칙을 따른 것이다. MIPS 어셈블리 언어를 기계어로 변환하면 다음과 같다. 위의 명령어 형식(instruction format)으로 나타낸 기계어는 "add $t0, $s1, $s..
컴퓨터가 수를 나타내는 법 컴퓨터는 일련의 높고 낮은 전기 신호의 형태로 숫자를 저장한다. 따라서 이진수를 사용한다고 볼 수 있다. 컴퓨터 내에서 모든 정보는 이진 자리 수(binary digit), 즉 비트(bit)로 구성되므로 비트가 계산의 기본 단위가 된다. 워드 내의 각 비트에 오른쪽에서 왼쪽으로 0, 1, 2, 3, ... 과 같이 번호를 붙인다. 워드는 위 그림처럼 수평뿐만 아니라 수직으로도 그릴 수 있기 때문에, 가장 오른쪽 혹은 가장 왼쪽 비트라고 말하면 표현이 애매할 수가 있다. 대신 LSB(Least Significant Bit)라는 용어로 가장 오른쪽 비트 0을 나타내고, MSB(Most Significant Bit)라는 용어로 가장 왼쪽 비트 31을 나타낸다. 2의 보수 MIPS 워..