2016년 3월 13일 일요일

Cache

1.Computer System Overview(16. 3. 9.)

9] cache memory
- cpu instruction execution 속도는 memory cycle 속도에 의해 제한된다.
(cpu의 처리속도에 비해 주 메모리의 속도가 아주 느리기 때문)
- cpu와 주 메모리 사이에 cache를 배치하여 문제 해결 가능(속도: cpu>cache>메모리)
- principle of locality(locality of reference) 때문에 작은 크기로 엄청난 효과를 지님
- 대부분의 메모리 접근은 특정한 위치의 근방에서 자주 일어나는 경향이 있다.

- cpu의 데이터 처리 단위는 word, 주 메모리도 word 단위로 구성되어 있음.
- cache Block(k word)단위로 데이터를 구성한다. , 필요한 데이터를 포함하는 block cache에 저장하여, cpu의 주 메모리 접근을 최소화해 효율을 높인다.
- cpu cache(word 단위 transfer), cache main memory(block 단위 transfer)

10] cache read operation
1. cpu로부터 RA(read address) receive
2-1. 캐시에 해당 데이터를 포함한 block이 존재한다면, cpu에 전달
2-2. 캐시에 없다면, 주 메모리에서 해당 데이터 포함한 block에 접근, 캐시에 공간 할당.
3. cpu에 전달 및 캐시에 해당 블록 전송

+] https://ko.wikipedia.org/wiki/CPU_%EC%BA%90%EC%8B%9C
CPU 캐시(CPU cache) CPU 구조에 메모리로 사용하도록 구성되었다. CPU 캐시는 메인 메모리에서 가장 자주 사용되는 위치의 데이터를 갖고 있는 크기는 작지만 빠른 메모리이다. 대부분의 메모리 접근은 특정한 위치의 근방에서 자주 일어나는 경향이 있기 때문에, 데이터를 크기는 작지만 속도가 빠른 캐시메모리에 복사해 두면 평균 메모리 접근 시간을 아낄 수 있다.

프로세서가 메인 메모리를 읽거나 쓰고자 할 때는, 먼저 그 주소에 해당하는 데이터가 캐시에 존재하는지를 살핀다. 만약 그 주소의 데이터가 캐시에 있으면 데이터를 캐시에서 직접 읽고, 그렇지 않으면 메인 메모리에 직접 접근한다. 이때 대부분의 프로세서는 메인 메모리에 직접 접근해서 전송된 데이터를 캐시에 복사해 넣음으로써 다음번에 같은 주소에 프로세서가 접근할 때 캐시에서 직접 읽고 쓸 수 있도록 한다.

11] cache design
- 캐시는 주 메모리의 일부분만 저장하므로 주소로 접근할 수 없다. 따라서 각 block에 메모리의 주소와 상태 등을 나타내는 tag를 달아서 관리한다.
- mapping function : determines which cache location the block will occupy
(캐시에서 데이터를 찾을 때 이쯤에서 찾아~ 라고 알려주는 역할)
- replacement algorithm: determines which block to replace(Least-Recently-Used)
- write policy : multicore, multiprocessor system에서 cache coherence 문제 발생
한 복사본이 갱신될 경우 가능한 한 빨리 모든 복사본이 갱신될 것을 보장해야 함.


interrupt 와 multiprogramming


1.Computer System Overview(16. 3. 9.)

4) interrupt

주 목적: cpu를 놀게 하지 말자!(cpu에 비해 I/O devices는 너무 느려서 device controller I/O comand를 수행하는 동안 cpu는 놀게 된다. 그냥 다음 instruction들을 수행 할 수는 없다. I/O device Data write의 성공을 보장할 수 없기 때문에, 반드시 후처리가 필요하다. cpu device controller I/O comand를 수행하는 동안 다른 일을 하다가, 끝나면 후처리를 하라고 알려주는 역할이 바로 interrupt)
interrupt the normal sequencing of the processor
하드웨어는 system bus를 통해, 소프트웨어는 system call을 통해 interrupt 발생시킴.

5) interrupt handler(ISR-interrupt Service Routine)

- interrupt 에 대응하여 특정 기능을 처리하는 기계어 코드 루틴.
각각의 I/O device마다 특정한 interrupt handler들이 존재하며, interrupt 발생시 interrupt vector를 사용하여 구별한다.
kernal의 일부분으로 memory fixed되어 저장된다.

6) interrupt cycle

1. instruction execution(fetch+execution)
2-1. interrupts disabled – 다음 instruction execution 계속 수행, 발생한 interrupt는 큐에 저장(IRQ)
2-2. interrupts enabled interrupt 발생시 interrupt handler initiate.
-   instruction 수행 후 마다 interrupt 발생 여부 확인 함.
-  disabled이여도, non-maskable interrupt가 존재(이를 위한 line 별도 존재)

7) interrupt processing

1. 현재 진행 중인 instruction을 완료한다.
2-1. CPU의 특수레지스터 중, interrupt mask 비트를 보고 mask 되면 무시 한다.
2-2. 아니라면, PC PSW control stack에 저장한다.
3. interrupt handler의 시작주소를 PC load한다.
(interrupt vector를 읽고, ISR의 주소값을 얻어 JUMP한다)
4. 현재 진행중인 프로그램의 register control stack에 저장한다.
5. interrupt handler를 수행한다.
6. register를 복원한다.
7. PSW PC를 복원한다.

- 1~3 Hardware, 4~7 Software에서 처리함.
- Control stack을 위한 stack pointer(top) cpu내에 존재

7) multiple interrupt
interrupt 수행도중 interrupt가 또 오면?
- 정책에 따라 결과가 다르다. 해당 interrupt 중단하고 새로운 interrupt 시작할 수도 있고, interrupt를 끝내고 시작할 수도 있다.

+] I/O
device controller는 특정 유형의 장치들을 담당하며, 지역 버퍼 저장 장치와 특수 목적용 레지스터 집합을 가진다. device controller는 자신이 제어하는 장치와 지역 버퍼간의 자료 전송을 담당한다. 운영체제는 장치 드라이버를 사용해 device controller를 관리한다.(장치 드라이버는 device controller의 레지스터에 명령 적재, device controller는 레지스터의 내용에 따라 장치로부터 지역버퍼로 자료전송)

8] multiprogramming
- interrupts를 사용해도 cpu가 항상 효율적으로 사용되는 것은 아니다.
ex) write 연산이 끝나지 않았는데, write를 또 해야할 때 cpu는 이전의 write 연산이 끝나고, interrupt가 오기를 기다려야 한다. (앞 뒤 I/O 간의 의존성 때문 - 하드디스크도 하나의 컴퓨터로, 속도를 높이기 위해 처리순서를 바꾸는 경우도 있다. 데이터가 덮어 써질 가능성이 존재한다.)
- 앞의 작업과 뒤의 작업이 전혀 상관관계가 없다면 문제 해결 가능
-> cpu가 동시에 여러 개의 프로그램을 수행 (multiprogramming 등장)

- 상대적인 우선순위 및 I/O 대기시간을 고려하여 순서가 결정됨. (CPU scheduling)
- interrupt handler 완료 후, 아무 프로그램으로나 돌아갈 수 있음.

+] multiprogramming, time sharing
multiprogramming은 여러 가지 시스템 자원을 효율적으로 이용할 수 있는 환경을 제공하지만, 사용자가 컴퓨터 시스템과 상호작용 할 수 있도록 하지는 않음.
이를 가능 하게 한 것이 time sharing(시분할, multi-tasking)
시분할 시스템은 multiprogramming의 논리적 확장으로, cpu가 다수의 작업을 서로 교대로 수행하지만, 매우 빈번하게 교대가 일어나기 때문에 사용자들은 각자 자기의 프로그램과 상호작용 할 수 있다. 또한, 시분할 시스템을 이용하면 동시에 많은 사용자가 하나의 컴퓨터를 공유할 수 있다.(시스템이 사용자 간에 매우 빠르게 전환되기 때문에, 각 사용자는 자신이 컴퓨터를 전용한다고 느낌)

multiprogramming, time sharing에서는 여러 작업이 메모리에 동시에 유지되어야 한다. 주 메모리는 모든 작업을 저장하기에는 너무 작기 때문에, 시스템에 들어온 모든 작업들은 디스크에 존재하는 작업 풀(job pool)에 보관된다. 이 작업들 중 메모리에 보관할 작업을 선택하는 것을 작업 스케줄링(Job scheduling)이라 한다.

메모리에 여러 프로그램이 동시에 있을 때, 이 중 실행할 작업을 고르는 것을 cpu 스케줄링(cpu scheduling)이라고 한다.


CPU와 Register

1.Computer System Overview(16. 3. 9.)

1) basic elements

proccessor + Main memory + I/O modules + System bus

- proccessor cpu(control unit + register + ALU)
- Main memory DRAM, volatile (비휘발성 memory –연구중),(real,primary memory)
- I/O modules secondary memory devices, communication equipment, terminals
- system bus cpu, memory, I/O modules communication

2) register
- CPU에 위치한 고속메모리.
- CPU가 반복적 또는 주기적으로 처리하는 도중의 일시적인 정보는 CPU 내부의 레지스터에 저장하는 것이 효율적
- 데이터를 저장하는 register 외에, 특수한 용도로 사용되는 register들이 존재함

1. User-visible registers

data regiser address register (index, segment pointer, stack pointer)

– 사용자가 main memory reference 최소화를 통한 optimize 가능
- machine language를 사용하여 모든 프로그램에서 접근 가능
(ex - c언어에서 자주쓰이는 부분을 어셈블리어로 embedding 하여 최적화)

2. User-Invisible registers(cpu 전용 레지스터)

1] internal register for data I/O
MAR(memory address register) - 다음번에 읽고 쓸 메모리의 주소를 저장
MBR(memory buffer register) - 메모리로부터 읽어온 or 써야할 데이터를 저장
I/O address register – 입출력 모듈의 주소 저장
I/O buffer register – 입출력 모듈과 cpu의 데이터 교환을 위해 사용.


2] Control and Status registers

PC(program counter) - 다음번에 fetch instruction의 주소 저장, fetch 1씩 증가
(fetch : memory로부터 instruction을 읽어서 IR에 저장하는 것)

IR(instruction register) - 가장 마지막에 fetch instruction 저장
- instruction categories
1] processor memory (load,store) 2] processor I/O device (read,write)
3] data processing (add,subtract..) 4] control (jump..)

PSW(program status word) - 연산이나 명령어 실행 후의 정보를 저장하는 제어 워드
- 모든 정보를 비트단위로, 하드웨어적으로 0 or 1로 설정하여 현재 상태 표시
1] condition codes(postive,negative,zero,overflow)
2] interrupt(enable,disable)
3] supervisor/user mode – 현재 instruction이 어느 권한의 code인지 저장

3] 연산관련 registers

AC(Accumulator)
- 데이터를 임시 저장하는 레지스터
기억장치로부터 가져온 데이터, 연산 수행후 결과 값 모두 AC에 저장된다.
Word(cpu가 한번에 처리 할수 있는 데이터의 비트 수) 단위

+] 커널모드와 유저모드

유저 애플리케이션이 운영체제에 치명적인 데이터에 접근하여 수정하거나 삭제하지 못하게 막기위해 윈도우는 두가지 프로세서 접근 모드를 지원함. 유저 어플리케이션은 유저모드에서만, OS코드(device driver, 시스템 서비스 등)은 커널 모드에서만 실행이 된다. 유저모드에서는 하드웨어에 직접 접근할수 없으며, 커널모드는 모든 시스템 메모리와 모든 cpu instruction에 접근이 허가된 실행모드이다.
유저 애플리케이션에서 하드웨어와 같은 시스템자원에 접근하기 위해서는 system call을 통해 커널모드에 진입하여야 함. 커널모드에서 작업 완료후 다시 유저모드로 전환됨.
하드웨어가 지원하는 dual mode가 없을 경우 운영체제에 심각한 결점을 초래할 수 있다. 예를 들어 잘못된 사용자 프로그램이 운영체제 부분에 자료를 덮어 운영체제를 지워버릴 수 있고, 여러 프로그램이 동시에 한 장치에 기록할 수도 있다.

+] system call

OS코드의 일부분으로 일종의 API(애플리케이션에서 사용할수 있도록 운영체제나, 언어가 제공하는 기능을 제어할수 있도록 만든 인터페이스의 집합체)
사용자가 커널에 진입할수 있는 유일한 수단.

Q] 왜 방금 수행한 연산의 결과(+,-,0,overflow..) PSW에 별도로 저장할까?
A] CPU내에 오류감지에 필요한 정보가 있어야, 빠르게 오류를 검출할 수 있음.
instruction이 끝날 때 마다 오류를 검사.

3) Instruction execution

1. fetch PC가 가리키는 memory 주소로부터 instruction을 읽어서 IR에 저장
1] MAR <- PC 2] MBR <- M(MAR), PC <- PC +1 3] IR <- MBR

2. execute instruction을 해독하고 명령을 실행.
ex) load 1] MAR <- IR 2] MBR <- M(MAR) 3] AC <- MBR
ex) add 1] MAR <- IR 2] MBR <- M(MAR) 3] AC <- AC + MBR
ex) store 1] MAR <- IR 2] MBR <- AC 3] M(MAR) <- MBR
cycle 1클록에 1번씩 이루어짐.

+] 32bit, 64bit의 차이

32비트 CPU 32비트 주소 지정 방식(32bit Addressing)을 사용하며, 그래서 할당할 수 있는 전체 메모리 공간의 개수도 이에 맞춰 최대 2^32개이다. 따라서 최대 4GB의 메모리를 사용할 수 있는 것.(물론 실제로는 3.5GB 정도임, reseverd된 영역 존재) 64bit의 경우 최대 16GB의 메모리를 사용 가능함.

2016년 3월 12일 토요일

C++ 공부 5 - 정보은닉(Information Hiding), 캡슐화(Encapsulation), 생성자(Constructor)

chap4. 클래스의 완성
 
1. 정보은닉(Information Hiding)
 
멤버변수를 private로 선언하고, 해당 변수에 접근하는 함수를 별도로 정의하여, 안전한 형태의 접근을 유도하는 것.
 
int GetX() const;
void ShowInfo() const;
 
- const 함수 : “이 함수 내에서 멤버변수의 값을 변경하지 않겠다의미
- const 함수 내에서 const 가 아닌 함수를 호출할 수 없음.
- const 참조자를 가지고 const 가 아닌 함수를 호출할 수 없음.
 
2. 캡슐화(Encapsulation)
 
관련 있는 함수와 변수를 하나의 클래스 안에 묶는 것.
 
3. 생성자(Constructor)
 
생성자 : Class 이름과 함수의 이름 동일, 반환형x, 오버로딩 가능.
매개변수의 defalut 값 설정 가능.(이 경우 유의)
객체 생성시 딱 한번 호출. 초기화에 사용.
 
SimpleClass c1(); // no
SimpleClass c1; // ok no-argument constructor 호출
SimpleClass * c1 = new SimpleClass(); // ok
 
- no-argument constructor 호출시, 동적 할당의 형태로만 호출할 것.
 
SimpleClass c1(20,40);
SimpleClass * c1 = new SimpleClass(20,40);
 
SimpleClass c2;
SimpleClass * c2 = new SimpleClass();
 
-같은 데이터를 가진 객체가 만들어지나일반적인 생성과, 동적메모리 할당의 차이가 있다는 것에 유념할 것.
 
4. 멤버 이니셜라이저(Member Initializer)
 
멤버변수로 객체를 가질 때 Member Initializer를 사용해 초기화한다.
 
Class Point{
      private:
            int x;
            int y;
      public:
            Point(const int &xp, const int &yp);
}
Point::Point(const int &xp, const int &yp){
      x = xp; 
      y = yp;
};
 
Class Rectengle{
      private:
            Point left;
            Point right;
      public:
            Rectengle(const int &x1, const int &y1, const int &x2, const int &y2);
};

Rectengle::Rectengle(
const int &x1, const int &y1, const int &x2, const int &y2) :left(x1,y1), right(x2,y2){ . . . . . . . }
 
- 클래스 내 선언은 그냥 해주고, 정의시에 “: + 객체의 constructor”
(물론, 밖에 안빼도 ok, 길면 빼고 아니면 같이 써버려~)
- ‘:left(x1,y1)’ : 객체 left 생성할 때 x1,y1을 인자로 받는 생성자 호출
- ‘right(x2,y2)’ : 객체 right 생성할 때 x2,y2을 인자로 받는 생성자 호출
 
+] 객체의 생성순서
1. 메모리할당.
2. Member Initializer로 멤버객체 초기화.
3. 생성자의 몸체 실행.
 
class FruitSeller{
      private:
            const int APPLE;
            int numOfApple;
            int &myMoney;
      public:
            FruitSeller(int price, int num, int &money)
: APPLE(price), numOfApple(num), myMoney(money)
{ . . . }
};
 
- Member Initializer로 변수 및 const 및 참조자도 초기화 가능
- “: 변수이름(argument)” 의 형태로 초기화 가능.
- 이 방식이 더 빠르고, 더 명확한 방법임.(변수 선언과 동시에 초기화)
 
+] malloc 사용시 공간 할당 후 생성자 호출하지 않음.
new 사용시 공간 할당 후, 생성자 자동 호출 (정의되지 않아도 defalut constructor 생성 후 호출 아무일도 하지 않음)
 
- defalut constructor는 어떠한 생성자도 정의되어 있지 않을때만 자동 생성됨.
- argument 받는 constructor만 있는데, no-argument로 생성시 에러.
- 특정 constructorprivate으로 선언시, 객체 생성방법 제한 가능.
 
5. 소멸자(Destructor)
 
class Person{
      private:
            char * name;
            int age;
      public:
            Person(char * myname, int myage){
            int len = strlen(myname)+1; //종료문자포함위해 +1
            name = new char[len]; //메모리절약 동적할당
            strcpy(name, myname);
            age = myage;
}
~Person(){
      delete []name;
}
 
};
 
- Destructor : “~”+“클래스 이름”+“()”의 형태로 정의. 반환형 없음.
- 객체 소멸과정에서 자동으로 호출되며, 따로 정의하지 않으면 defalut 소멸자가 자동 생성됨.
- Class 내에서 동적할당한 공간이 있다면 반드시 delete통해 해제할 것.
 
6. 객체 배열
 
SoSimple * p1 = new SoSimple[10];
 
- SoSimple Class의 객체 10개 생성.
- 배열로 생성시, no-argument constructor가 자동 호출됨.
- (다른 인자전달 constructor 사용 불가!)
- 이후 for문 이용해, 일일이 초기화 해야함.(constructor 사용 불가!)
 
7. 객체 포인터 배열 을 쓰면 되지~
 
Person * parr[3];
char name[100];
int num;
 
for(int i = 0; I < 3 ; i++){
      cin>>name; cin>>num;
      parr[i] = new Person(name,num);
}
 
delete parr[0];
delete parr[1];
delete parr[2];
 
- new 써서 동적메모리 할당 했으니, delete 해줘야 함.
 
8. this 포인터
 
this 포인터는 해당 객체의 주소를 가리키는 포인터임.
 
Circle donut;
Circle * p;
p = &donut;
double d = p -> getarea();
 
- 객체 이름으로 멤버에 접근할 때는 . 연산자를 이용하지만객체 포인터로 멤버에 접근할 때는 -> 연산자를 사용한다.
 
class TwoNumber{
      private:
            int num1;
            int num2;
      public:
            TwoNumber(int num1,num2){
            this->num1 = num1; //해당 객체의 멤버변수 접근
            this->num2 = num2;
            }
}
 
- 같은 이름을 가진 변수구분에 아주 유용하다.
 
 
9. self-reference 반환
 
Class SelfRef{ 
      private:
            int num;
      public:
            SelfRef(int n) : num(n){...}
            SelfRef& Adder(int n){ //class의 참조값 리턴.
            num += n; 참조값으로 받으면, 직접접근 가능.
            return *this;
            }
}
 
SelfRef obj(3);
SelfRef &ref = obj.Adder(5); //참조값 리턴이니 참조값으로 받음.
ref.Adder(7).Adder(3);
 
- 객체 포인터(->)가 아닌 참조값(.)으로 직접 접근이 가능함.