2장. 생능_컴퓨터구조론_연습문제

728x90

2.1

: 3.0 ns

풀이)

1클록 당 0.5 ns 시간이 걸리고, 파이프라이닝 되지 않은 기본 명령어 실행 상태이므로

인출 사이클 : 0.5ns X 3 = 1.5ns

실행 사이클 : 0.5ns X 3 = 1.5ns

따라서 ‘ADD addr’ 명령어의 총 실행 시간은 1.5 + 1.5 = 3.0ns 가 된다.

2.2

2.2-(1)

풀이) 기억장치

주소 내용
200 1300
201 6301
202 2302
203 8250
300 0009
301 0005

 

200번지 명령어 수행

PC 0201
AC 0009
IR 1300

 

[M] 기억장치 200번지의 명령어: LOAD 300 ( 300번지 내용을 AC로 이동)

AC: 0009 (명령어 실행 결과 300번지의 내용인 0009가 적재된다.)

IR: 1300 (최근 실행된 명령어 코드가 적재된다,)

PC: 201 (현재의 200번지 명령어 실행 후 다음 실행할 명령어 주소는 +1 처리된 201번지)

 

201번지 명령어 수행

PC 0202
AC 0004
IR 6301

[M] 기억장치 201번지의 명령어: SUB 301 (현재 AC값에 301번지 내용을 뺀 값 AC에 적재)

AC: 0004 (원래 AC 값인 9에서 301번지 내용인 5를 뺀 0004AC에 최종 적재된다.)

IR: 6301 (최근 실행된 201번지의 명령어 코드가 적재된다.)

PC: 202 ( 다음 명령어 주소는 202번지)

 

202번지 명령어 수행

PC 0203
AC 0004
IR 2302

[M] 기억장치 202번지의 명령어: STA 302 ( AC의 내용이 302번지에 저장)

AC: 0004 0004 (AC의 값이 메모리 302번지에 저장되는 명령어라 AC값 자체는 변함X)

IR: 2302 (최근 실행된 202번지의 명령어 코드 ‘2302’ 가 적재된다.)

PC: 203 (다음 명령어 주소는 순차대로 203번지가 된다.)

 

203번지 명령어 수행

PC 0250
AC 0004
IR 8250

[M] 기억장치 203번지의 명령어: JUMP 250 (분기될 주소 250번지가 PC에 적재)

AC: 0004 (영향 없다.)

IR: 8250 (최근 실행된 203번지의 명령어 코드 8250이 적재된다)

PC: 203 250 (분기 명령어 실행 결과, 다음 실행 명령어 주소는 250번지가 된다.)

 

2.2-(2) : PC 450 AC 0004 IR 6301 SP 998

풀이)

PC 450 (이유) : 201번지의 명령어 SUB 301 실행 도중 발생한 인터럽트 요구이므로

원래 실행 중이던 SUB 301을 마저 처리한 뒤 다음 실행할 명령어 주소로 ISR의 시작주소인 450번지를 PC에 적재한다.

AC 0004 (이유) : 인터럽트 요구가 들어오더라도 원래 실행 중이었던 SUB 301 실행은 마저 완료하고 인터럽트가 처리되기 때문에 AC에는 기존 명령어 처리 결과값인 0004가 적재된다.

IR 6301 (이유) : 기존에 실행되었던 명령어 코드가 6301 이기 때문이다.

SP 998 (이유) : 스택 포인터 초기값은 999번지였는데 원래 PC에 저장되어있던 (복귀주소) 202번지가 메인 메모리 999번지 스택에 적재되면서 가장 최상위 스택 주소를 가리켜야 하는 SPSP1이 되어 998번지를 가리키게 된다.

 

2.3 : 999번지 스택에 저장/ SP998로 변경.

풀이) 원래 SP가 가리키던 999번지의 스택에 저장이 되고, 이후 SP는 가장 최상위 스택 주소를 가리켜야 하므로 SP-1이 되어 998번지를 가리키게 된다.

 

2.4 : 인터럽트 플래그 상태로 만든다.

풀이) 우선순위가 높은 인터럽트 요구도 무시하려면 인터럽트 플래그 상태(불가능 상태)로 만들어야 한다. 그렇게 되면 새로운 어떤 인터럽트 요구 들어오게 되어도 인터럽트 사이클이 수행되지 않고 기존 루틴의 수행이 지속된다.

 

2.5 : 클록 주기 1003/ 소요되는 전체 시간 501.5ns

풀이)

클록 주기 : 4 + (1000-1) = 1003

 

전체 소요 시간 : 2GHz = 0.5ns , 1003 X (0.5ns) = 501.5 ns

 

2.6 : 시간: 252.75ns / SP= 11.86 / E=0.989

풀이) 4GHz = 0.25ns

T12 : { 12 + (1000-1) } X 0.25 ns = 252.75 ns

T1 : { 12 X 1000 } X 0.25ns = 3000ns

SP = T1 / T12 = 11.8694...

E = SP / 12 = 0.9891...

 

2.7

2.7-(1) : 7ns, 52ns, 502ns, 5002ns

N= 10 : { 5 + (10-1) } x 0.25ns = 7ns

N= 100 : { 5 + (100-1) } x 0.25ns = 52ns

N= 1000 : { 5 + (1000-1) } x 0.25ns = 502ns

N= 10000 : { 5 + (10000-1) } x 0.25ns = 5002ns

 

2.7-(2) : 3.571/4.807/4.98/4.998

풀이)

N=10 SP = (2.5ns X 10) / 7ns = 3.571

N=100 SP = (2.5ns X 100) / 52ns = 4.808

N=1000 SP = (2.5ns X 1000)/ 502ns = 4.98

N=10000 SP = (2.5ns X 10000)/5002ns = 4.998

 

2.7-(3) 다음 그래프는 N값에 따른 결과값을 그래프화 한 것이다.

2.8

2.8-(1) : 3400 ns

풀이) ‘파이프라인을 이용하지 않는다는 가정이 있기 때문에, 1000개의 명령어들은 각각 명령어 처리를 위해 할당된 단계들을 별도로 실행하게 될 것이다.

1000개의 명령어 중 10%에 해당하는 100개의 명령어는 2 클록씩 명령어 처리를 거친다.

100 X 2 = 200 ns

1000개의 명령어 중 40%에 해당하는 400개의 명령어는 3 클록씩 명령어 처리를 거친다.

400 X 3 = 1200 ns

1000개의 명령어 중 나머지에 해당하는 500개의 명령어는 4 클록씩 명령어 처리를 거친다.

500 X 4 = 2000 ns

따라서 200 + 1200 + 2000 = 3400 ns 가 답이 된다,

 

2.8-(2) : 1003 ns

풀이) 문제에서 주고 있는 명령어 파이프라인은 4단계 파이프라인이기 때문에 (각각의 실제 필요한 단계들을 무시하고) 4단계의 파이프라인을 일괄 적용해야 한다.

따라서 1000개의 명령어에 4단계 파이프라인을 거치게 된다면

k=4, N=1000, T = 4 + ( 1000-1) = 1003 ns 가 된다.

 

2.8-(3) : SP = 3.389 / E= 0.849

풀이) SP = 3400ns / 1003ns = 3.389

E = 3.389 / 4 = 0.849

 

2,9

2.9-(1) : 3.25ns

풀이) 하나의 명령어 실행 시간은 각 사이클 처리 시간을 모두 합한 값이다.

0.5ns + 1.0ns + 1.0ns + 0.75ns = 3.25ns 가 된다.

 

2.9-(2) : 클록주기 1.0ns // 주파수: 1 GHz

풀이) 앞서 (1)에서 알 수 있듯 각 사이클 처리 시간이 제각각이기 때문에 모든 단계에

공통의 파이프라인 클록을 입히기 위해서는 가장 긴 시간을 기준으로 해야 한다. 따라서 가장 긴 시간인 1ns를 클록 주기로 하여 4단계 명령어 파이프라인을 만들어야 한다.

 

2.9-(3) : 한 개 명령어 실행 시간= 4ns

(1)결과와 비교 : 속도 효율을 높이기 위해 사용했던 파이프라인을 입혔는데 되려 속도 효율이 저하된 것을 확인할 수 있다. 이는 파이프라인의 클록 설정시 가장 오래 걸리는 단계의 시간을 기준으로 1클록을 설정하게 되기 때문에 불필요한 시간을 소모하게 된 것이다.

 

2.9-(4) : 325ns /103ns / SP = 3.15

풀이) 100개의 명령어 실행 시간을 (1)(3)의 조건으로 각각 구한 뒤 SP를 구하고자 한다, 우선 (1) 조건 하에 걸리는 시간은 3.25ns X 100 = 325 ns 이다.

이어서 (3) 조건 하에 걸리는 시간은 { 4 + (100 1) } X 1ns = 103 ns 이다.

SP = 325 / 103 = 3.15 가 된다.

 

2.10

2.10-(1) : 2.5GHz

풀이) 명령어 파이프라인은 처리 기간이 가장 긴 주기를 기준으로 클록 주기를 설정하게 되기 때문에 OF 단계의 처리 시간을 기준으로 파이프라인 클록 주파수를 최대 2.5GHz로 설정해야 한다.

2.10-(2) : 400ns

풀이) 4단계 명령어 파이프라인으로 1000개의 명령어를 순차 실행할 때 걸리는 시간은

{ 4 + (1000-1) } x 400ps = 400ns 가 된다.

2.10-(3)

: EX단계의 처리 시간을 단축시켜도 여전히 OF단계의 주기가 가장 길기 때문에 이 명령어 파이프라인은 OF단계의 주기를 기준으로 파이프라이닝 될 것이다. 따라서 전체 성능에 도움이 되지 않는다.

2.10-(4)

: EX 단계의 처리 시간이 기존의 OF 단계 처리 시간보다 더 길어진다면 파이프라인의 성능은 당연히 더 떨어지게 된다. 이 경우 처리 시간은 1003 X 500ps = 500ns 가 된다. 기존의 (2)번 처리 결과보다 시간이 더 길어진 것을 확인할 수 있다. 이는 명령어 파이프라인이 처리 시간이 가장 긴 것을 기준으로 각 단계 주기를 설정하기 때문에 소모적인 처리 시간이 생기면서 발생한 비효율로 볼 수 있다.

 

2.11 : 18사이클

풀이) 4단계 명령어 파이프라인 실행 중 5번째 명령어가 분기 명령어가 되면 분기 명령어를 기준으로 그 전과 후의 실행 사이클을 확인하면 된다.

분기 전: 4 + ( 5-1) = 8

분기 후: 4 + ( 7-1) = 10 따라서 전체 사이클은 총 10 +8= 18 사이클이 걸린다.

 

2.12

2.12-(1) : 104ns

풀이) T = 5 + (100 1) = 104 ns

 

2.12-(2) : 54ns / SP = 1.925

풀이) 2-way 슈퍼스칼라 구조로 변경하게 되면 T = k + (N-m)/m의 공식으로 실행 시간을 구해야 한다. 따라서 5 + (100 2) / 2 = 54ns 가 된다.

또한, (1)의 결과와 비교하여 SP를 구해야 하므로 104 / 54 = 1.925 가 된다.

2.13 : 최대 20

풀이) p.85를 참고했다. 슈퍼스칼라 프로세서의 속도는 파이프라인을 사용하지 않은 프로세서에 비하여 최대 mk배까지 속도향상을 얻을 수 있다고 되어있다.

이에 따라 5단계 명령어 파이프라인들로 이루어진 4-way 슈퍼스칼라 프로세서를 이용하게 되면, k= 5 , m = 4 mk= 20 으로 최대 20배까지 속도향상을 얻을 수 있게 된다,

2.14

: 듀얼-코어와 멀티-코어 프로세서는 여러 개의 독립적인 태스크 응용 프로그램들을 동시에 처리하는 방식으로 시간 단축을 도모하는 프로세서다. 그런데 만약 문제에서 요구하듯 단 하나의 독립적인 태스크 응용 프로그램을 처리할 것이라면 듀얼-코어 프로세서가 되려 소모적인 처리 시간을 갖게 될 것이다. 따라서 하나의 독립 프로그램 처리 시에는 일반 프로세서를 이용하는 것이 더 효율적이다.

또한, 듀얼-코어와 멀티-코어가 CPU 코어 수 만큼의 성능 향상을 얻기 위해서는 내부적으로 여러 개의 스레드들로 분할되는 응용 프로그램을 처리하는 환경이 유리하다.

2.16

2.16-(1)

1-주소 명령어는 한 개의 오퍼랜드를 포함하는 명령어이다.

LOAD A : AC <- M[A]

ADD B : AC <- AC + M[B]

STOR T : M[T] <- AC

// A+B 연산 후 기억장치의 T번지에 저장한다.

LOAD E: AC <- M[E]

MUL F: AC <= AC X M[F]

STOR U : M[U] <- AC

// E x F 연산 후 기억장치 U번지에 저장한다.

LOAD G: AC <- M[G]

MUL H : AC <- AC x M[H]

STOR V : M[V] <- AC

// G x H 연산 후 기억장치 V번지에 저장한다.

LOAD D: AC <- M[D]

SUB U: AC <- AC M[U]

ADD V: AC <- AC + M[V]

STOR W: M[W] <- AC

// D- (E x F)를 한 후 이 값에 + (G x H) 한 값을 기억장치 W번지에 저장한다.

LOAD R: AC <- M[T]

DIV W : AC <- AC/M[W]

STOR X: M[X] <- AC

// T의 값을 W의 값으로 나누고 최종 답을 기억장치 X번지에 저장한다.

 

2.16-(2)

2-주소 명령어는 2개의 오퍼랜드를 포함하는 명령어이다.

 

MOV R1, A : R1 <- M[A]

ADD R1, B : R1 <- R1 + M[B]

// A+B 실행한 값을 R1에 저장한다.

MOV R2, E : R2 <- M[E]

MUL R2, F : R2 <- R2 x M[F]

// E x F 연산한 값을 R2에 저장한다.

MOV R3, G : R3 <- M[G]

MUL R3, H : R3 <- R3 x M[H]

// G x H 연산 값을 R3에 저장한다

MOV R4, D : R4 <- M[D]

SUB R4, R2: R4 <- R4 R2

// D값에서 R2를 뺀 값을 다시 R4에 저장한다.

ADD R4,R3: R4 <- R4 + R3

// R4R3를 더한 값을 다시 R4에 저장한다.

DIV R1, R4 : R1 <- R1/ R4

MOV X, R1: M[X] <- R1

//R1R4로 나눈 값을 R1에 저장한 뒤 R1 값을 기억장치 X번지에 최종 저장한다.

 

2.16-(3)

3-주소 명령어는 3개의 오퍼랜드를 포함하는 명령어이다.

 

ADD R1, A, B : R1 <- M[A] + M{B}

MUL R2, E, F : R2 <- M[F] x M[F]

MUL R3, G,H : R3 <- M[G] x M[H]

SUB R4, D, R2 : R4 <- M[D] - R2

ADD R5, R4, R3 : R5 <- R4 + R3

DIV X, R1, R5 :M[X] <- R1/ R5

 

2.17

PUSH A: TOS <- A

PUSH B: TOS <- B

ADD: TOS <- (A+B)

// (A+B) 연산값을 TOS에 저장

PUSH C: TOS <- C

PUSH D: TOS <- D

SUB: TOS <- (C-D)

// (C-D) 연산값을 TOS에 저장

MUL: TOS <- (C-D) x (A+B)

POP X: M[X] <- TOS

// POP명령어를 통해서 최종 연산 값이 저장되어 있는 TOS내용을 인출하여 기억장치 X번지에 저장

 

2.18

(1) : A B + C D E +

(2) : A B + C D x E +

(3) : A B x C D x + E -

(4) : A B C D E x F/G /x E x

 

2.19

(1) : 1024 바이트

풀이) 16비트 명령어에서 OP코드에 6비트가 할당되었다면, 나머지 10비트가 직접 주소지정 가능한 필드가 된다. 직접 주소지정 될 수 있는 기억장치의 용량은 210승에 해당하는 1024 바이트가 된다.

 

(2) : -512 ~ 511

풀이) 10비트가 할당될 오퍼랜드 필드에 2의 보수 데이터를 저장하게 되면, 2의 보수는 가장 좌측 비트를 부호비트로 사용하기 때문에 1개의 비트를 제외한 나머지 9비트에 한해서 데이터의 범위를 구할 수 있다. 따라서 29승에 해당하는데 음수와 양수 범위를 아울러 데이터 범위를 구했다. : -29~( 291 )

2.20

(1) : 연산코드 필드= 7 비트/ 레지스터 필드 = 4 비트 / 주소필드 = 21 비트

풀이) 128가지의 연산을 수행하는 CPU7비트를 OP코드에 할당하고 있는 것이고, 내부 레지스터가 16개이므로 4비트를 레지스터 필드로 사용하고 있는 것이다. 그리고 그 외의 21비트에 주소 필드를 할당하고 있다.

(2) : -220~ (220-1 )

풀이) 주소 필드에 2의 보수로 표현되는 변위 주소로 사용한다고 했으므로 할당된 21비트에서 가장 좌측의 한 비트는 부호비트로 사용하고 나머지 20비트에 한해 사용할 수 있다. 따라서 변위의 범위는 220승에서 (220-1) 이 된다.

(3) :

2.21

(1) 즉시 주소지정 방식 : 1

이유) 이 방식은 명령어 내부에 데이터를 가지고 있기 때문에 데이터 인출을 위해 메모리에 갈 필요가 없어진다. 명령어 실행 후 데이터 저장시 한 번의 기억장치 액세스 필요하다.

 

(2) 레지스터 주소지정 방식: 2

이유) 이 방식은 필요한 데이터를 CPU 내부 레지스터에 저장하고 있기 때문에 데이터 인출을 위해 메모리로 가는 것이 아니라, CPU 내부의 기억장치인 레지스터를 액세스한다. 실행 후 데이터 저장 위치도 다시 CPU내부 레지스터가 되므로 총 2번의 기억장치 액세스가 필요하게 된다.

 

(3) 간접 주소지정 방식: 3

이유) 이 방식은 명령어 오퍼랜드 필드에 처리할 데이터의 주소를 간접적으로 저장하고 있기 때문에 기억장치의 해당 주소로 가서 실제 데이터 주소 액세스를 한 뒤 실제 주소로 다시 가서 데이터를 읽어오는 2번의 인출 액세스가 필요하다. 이후 명령어 실행된 데이터를 다시 기억장치에 액세스 해야 하므로 총 3번의 액세스가 필요하게 되는 것이다.

 

(4) 인덱스 주소지정 방식: 3

 

 

2.22

(1) : 203

이유) 명령어 레지스터 필드에 1이 저장되어있기 때문에 2-24 표의 R1을 읽어야 하는데, 레지스터 주소지정 방식은 사용할 데이터를 내부 레지스터에 저장해두는 방식이기 때문에 R1의 내용물인 203이 사용될 데이터임을 추론할 수 있다.

(2) : 4457

이유) 레지스터 간접 주소지정 방식이 사용됐다면 R1이 가리키고 있는 203은 사용할 데이터의 주소를 의미하므로 기억장치의 203번지로 다시 가서 데이터를 읽어야 한다. 2-24 표를 참고할 때 그 메모리의 203번지에는 4457 값이 저장되어 있다.

 

2.23

(1) : EA = (X2)

이유} 간접 주소지정 방식은 오퍼랜드 필드에 처리할 데이터의 주소를 데이터화하여 저장하기 때문이다.

(2) : EA = X1 + X3

이유) 인덱스 주소지정 방식은 X1을 기준으로 IX 내용인 X3를 더하여 유효주소를 결정한다.

 

2.24

(1) : EA = X2

이유) 직접 주소지정 방식을 이용하면 명령어 주소 필드 내용인 X2 번지에 사용할 데이터가 들어있는 것이기 때문에 유효주소는 EA = X2가 된다.

 

(2) : EA = X3

이유) 간접 주소지정 방식을 이용하면 X2 내용이 사용할 데이터의 주소가 된다.

따라서 EA = (X2) 가 되는데 X2 주소에 가면 X3이 저장되어 있기 때문에 최종 유효주소를

EA = X3 로 나타냈다.

 

(3) : EA = X1 + X2

이유) 상대 주소지정 방식을 이용하게 되면 유효주소는 PC의 내용과 직접주소지정 방식으로 나온 유효주소를 더해서 결정된다. 따라서 (PC) + X2 가 되는데 PC의 내용은 X1이므로

최종 유효주소를 X1 + X2 로 나타냈다.

 

(4) : EA = X2 + X4

이유) 인덱스 주소지정 방식을 이용하면 유효주소는 직접주소지정방식의 주소에 IX의 내용을 더해서 결정된다. EA = X2 + (IX) 가 되는데 IX의 내용이 X4 였으므로 최종 유효주소를

EA = X2 + X4 로 나타냈다.

 

2.25 : X1430을 가지게 된다.

풀이) PC의 내용인 X1= 454, 인출된 이후 PC내용은 +1 되므로 455 가 된다.

EA = A + (PC) 이므로, -25 + 455 = 430 이 된다.

 

2.26

(1) : 332의 보수인 ‘0100001’ 이 들어가야 한다.

풀이)

251 + x = 284

x= 33, +332의 보수로 표현하면 부호비트 0을 써준 뒤 0100001 로 표현하면 된다.

 

(2) : -192의 보수인 ‘101101’ 이 들어가야 한다.

풀이)

251 + x = 232

x= -19, -192의 보수는 부호비트 1을 써준 뒤 ‘101101’로 표현하면 된다.

 

2.27 : 오퍼랜드 필드에 200을 저장하고 레지스터 필드에 11을 저장한다.

 

2.28 : A=0 이 되면 된다.

풀이) EA = (R)

EA = (R) + A (, A는 명령어의 주소필드 내용)

따라서 A = 0 인 경우에 EA 가 같아진다.

728x90