블리는 어썸할거야/진행 내역 (rev. 1.1)
- 2019.3.19
- 배경 지식(?) 및 1,2단원 정리
- 현대 컴퓨터의 대부분은 폰 노이만 구조를 따르고 있음
- 프로세서(ALU,레지스터), 컨트롤 유닛(CU), 메모리(RAM), 외부 대용량 저장소(HDD,SSD), I/O
- 컴퓨터 살 때 뭐 사죠?
- CPU, RAM, 그래픽카드, 모니터/마우스/키보드, 하드디스크, SSD 등등
- 기본적인 구조인 프로세서 <-> 메모리를 어떻게 구현했는지
- 컴퓨터 구조에 대한 간단한 설명
- CPU,Memory, I/O Devices가 있고 각각이 Data bus, Control Bus, Address Bus가 연결하고 있음
- 메모리 계층
- (레지스터) -> 캐시 -> 메인 메모리(RAM) -> 보조 메모리(HDD,SSD)
- 명령어 실행 과정
- (명령어 인출 -> 실행) 반복한다
- 파이프라이닝이나 인터럽트 등의 이유로 여러 과정이 추가되거나 과정이 나눠질 수 있지만, 기본적으로 이렇다
- 1단원
- 코드 -> (컴파일러) -> 어셈블리 코드 -> (어셈블러) -> 기계어
- 어셈블리어와 기계어는 1:1로 매칭됨
- 2진수 표현
- 어차피 논리회로 때 다 배웠을 것이다
- 오버플로우에 대한 얘기 -> MSB로 들어오는 캐리와 나가는 캐리가 다를 때
- 2단원
- 배경 지식 할 때 했던 것들
- 파이프라인
- 앞서 진행했던 명령어 실행 과정을 여러 개로 나눌 수 있음
- 빨래통->세탁기->건조기->옷장을 예로 들어 설명
- x86은 명령어 실행 단계를 6단계로 나눌 수 있는데, 각각의 실행 단계를 물리적으로 분리할 수 있음
- 각각의 단계를 병렬적으로, 6개의 명령어를 병렬적으로 동시 수행하여 속도/클럭 속도를 대략 6배 정도 증가시킬 수 있음
- 슈퍼스칼라 (멀티코어 프로세서)
- 파이프라이닝 6단계 중 한 단계가 오래 걸린다면, 그것 때문에 클럭 속도를 늦추는 건 비효율적임
- 예를 들어 실행 단계에서 두 클럭 이상의 시간이 걸린다면, 실행 단계를 처리하는 모듈을 추가로 배치해서 속도를 올릴 수 있음
- ex) 실행 단계 처리하는 하드웨어 1에는 홀수 번째 명령어만 보내고, 짝수 번째는 하드웨어 2로 보냄
- 메모리 읽기
- 1단계: 주소 버스에 읽고자 하는 주소가 올려짐
- 2단계: 메모리의 read 플래그가 0으로 변경됨
- 3단계: data bus에 값이 읽힘
- 4단계: 메모리의 read 플래그가 1로 변경됨
- 캐시 메모리
- 캐시 메모리 -> 메인 메모리(RAM) -> 보조 메모리(HDD,SSD)
- 오른쪽으로 갈수록 용량 당 가격(현금)이 저렴해지고, 속도가 느려짐
- 1개의 프로그램을 실행하는 상황을 가정해보자
- 프로그램 전체가 메인 메모리에 올라가고, 일부를 캐시에 가져옴
- 찾고자 하는 데이터가 있으면 먼저 캐시에 있는지 보고, 아닐 때 메인 메모리에 접근해서 가져옴
- 캐시에 접근할 때는 1클럭만에 접근할 수 있지만, 메인 메모리에 접근할 때는 수십 클럭이 걸림
- 캐시 Hit 비율을 높게 잡는 게 중요하겠죠
- 2019.5.25
- 12단원
- float,double 등의 실수 값은 컴퓨터로 어떻게 저장되는가
- 먼저 10진수를 표현하는 방법으로 접근해보자
- 123.4567에서 각각의 자리는 10^2, 10^1, 10^0, 10^-1, 10^-2.... 자리다
- 다음 표현들은 다 같은 값이다
- 123.4567
- +1.234567e+02
- + 1.234567 * 10^2
- 마지막 표현 방법으로 수를 표기할 때, 어떠어떠한 정보가 있으면 수를 확정할 수 있을까?
- 부호
- 유효숫자?
- 10의 지수 (exponent)
- 위 3개의 정보가 필요하다는 것을 알고 가자
- 2진수로 표현한 실수를 보자
- 2진수 101.1011은 각 자리가 2^2, 2^1, 2^0, 2^-1, 2^-2, 2^-3, 2^-4
- 값은 4 + 1 + 1/2 + 1/8 + 1/16이 되겠죠?
- 위에서 했던 10진수 표현과 같이 여러 가지 방법으로 표현해보자
- 101.1011
- +1.011011 * 2^2
- 여기서도 필요한 정보는 sign, fraction, exponent
- 2진수로 표시하면, 값이 정확히 0이 아닌 경우는 맨 앞의 수가 무조건 1이다
- 지수는 음수가 될 수 있다
- 이 3개의 정보를 32비트(float) 또는 64비트(double) 안에 넣는 방법?
- IEEE-754
- 위에서 말한, 비트 안에 정보를 저장하는 방법의 표준
- float
- 1비트 sign, 8비트 exponent, 23비트 fraction
- double
- 1비트 sign, 11비트 exponent, 52비트 fraction
- float 기준으로 설명해보자
- 유의할 점
- exponent는 0 이하의 수일 수 있기 때문에, 비트 10000000이 기준 값(0)이 됨
- 이 값보다 1씩 작아질수록 exponent가 작아지고, 커질수록 exponent가 커짐
- ex) 10000011: 지수 3, 01111101: 지수 -2
- 위에서 언급한 것처럼, 지수 형태로 표현했을 때 맨 앞의 수는 원래 수가 0이 아닌 경우 무조건 1임
- 맨 앞의 1은 저장할 필요가 없다
- 0을 저장하는 방법은 뒤에 따로 있음
- 방법
- 맨 앞의 1비트에 부호 저장(음수면 1, 양수면 0)
- 다음 8비트에 지수 저장 (기준:10000000)
- 나머지 23비트에 소수점 이하의 비트 그대로 저장
- ex) 3.25
- 3.75 = 2 + 1 + 0.25
- 2진수로 11.01 = 1.101 * 2^1
- 부호비트: 0
- 지수비트 10000001
- 가수비트 101
- 따라서 float로 표현하면 0 10000001 1010000000000....000
- 컴퓨터구조때 다시 배운다아아