지금까지는 순전히 정수만 다뤘다. 사실 메모리의 비트도 하나하나가 정수이고, 거기에 메모리를 이동할 때도 비트연산만 했기 때문에 실질적으로 실수를 다룰 일은 거의 없었다. 하지만 컴퓨터의 원래 목적은 실험의 데이터를 뽑아내는데 있었고, 이때는 정확성 측면에서 실수가 필요하다. 물론 요즘에 와서는 실수 연산을 필요로 하는 프로그램은 적어졌지만, 그때의 그 흔적이 프로세서에 남아있는데 이걸 FPU(Floating Point Unit) 라고 한다. 흔히 부동소수점 연산기라 불리는데 과거에는 x87 coprocessor라는 이런 실수 연산에 특화된 장치를 현재의 프로세서에 이식되어 있다. 일단 프로세서가 주로 하는 일은 연산이다. 연산을 하기위해서는 당연히 인자가 필요할 것이고, 이 인자를 계속 가지고 있을 그..
지금까지 task를 효율적으로 처리할 수 있는 방안에 대해 이야기 했었는데 그러면 어떤 원리로 처리가 되는지를 알아봐야 할 것 같다.일단 task는 하나의 실행단위이다. 프로그램이 코드로 작성되어있는 집합일 뿐 이걸 pc가 동작시키기 위해서는 메모리상에 load를 시켜야 한다. 그 memory 상에서 대기하는 형태가 바로 task 인 것이다. 이 걸 다르게 말하면 Process라고도 할 수 있는데 실질적으로 큰 차이를 나타내는 것 같진 않다. 찾아보니까 task와 process의 구분은 MultiTasking의 개념을 설명하기 위해서 한다고는 하는데 자세히는 잘 모르겠다. 아무튼 이런 process가 동시에 처리 되는 것을 앞에서 잠깐 언급한 MultiTasking / MultiProgramming 이란..
이제 Task가 multilevel Queue 구조에 따라서 우선 순위가 결정되고 효율적으로 처리되는 것을 구현했는데, 다시 원론으로 돌아가 생각해볼 게 있다.task를 수행하기 위해서는 시스템내의 resource를 점유한다. 그런데 이전 예제처럼 수백 수천개의 task가 수행될때 가끔 같은 resource를 사용해야 할 경우가 발생할 수 있을 것이다. 분명 자기 task를 수행하기 위해서 resource를 점유한 상태에서 다른 task의 요청을 받게 되면 어떻게 해야 되는지에 대해 고민할 필요가 있다. 물론 운이 좋게 resource를 넘겨줄 수 있을 수도 있겠지만, 운영체제 구동에 운을 개입시키기에는 너무 큰 개체다. 이때 필요한 것이 Process synchronization( 동기화)라는 것이다...
지난 포스트에서 이야기 했던 것처럼 Round-Robin 방식을 쓰면 그냥 단순한 방식보다는 효율적으로 Task를 처리할 수 있다. 하지만 어떤 경우에는 기존 방식과 차이가 없는 경우도 발생하는데 이 때문에 조금더 발전한 방식이 바로 지난 포스트에서 잠깐 언급했던 우선순위를 도입한 방식이다. 이를 단계를 여러개로 구분했다 하여서 multilevel Queue Scheduler 이다. 당연한 이야기이겠지만 분명 queue가 필요하다는 말은 처리해야 될 task가 여러개 있다는 것이고 이걸 나눠서 처리하기 위해서는 따로 상태를 저장해둘 공간이 필요하다. 그리고 어떤 우선순위의 기준으로 볼것인가를 정해야 한다. 생각해볼 것은 큐에서도 여러 큐중 우선 순위가 높은 큐를 찾는 것이 우선이 되어야 할 것이고 그 안..
지난 포스트에서 임의의 task를 두개 만들고 서로 번갈아가면서 switch 하는 모습을 봤다. 그런데 이런 task가 두개 였으니까 이렇게 쉽게 switch가 되겠지만 실질적으로 처리하는 task는 엄청 많다. 이를 한꺼번에 다루기 위해서 뭔가의 도구가 필요하고 그 순서를 가를 기준이 필요하다. 그게 바로 scheduler 이다. 여러가지 이유가 있겠지만 기준을 정해서 task의 우선순위를 정하게 되면 시스템은 효율적으로 일할 수 있기 때문에 근본적으로 성능이 향상된다. 마치 계획성있는 사람이 더 효율적인 것처럼... 그 scheduler도 내부 구조와 기준에 따라서 나눠지는데 가장 쉽게 구현할 수 있는 기준이 바로 Round-Robin 기법이다. 그냥 전체 프로세스를 일정시간단위로 끊어가면서 task..
OS에서 가장 중요한 요소 중 하나가 바로 task를 처리하는 방법이다. task는 그냥 하나의 작업 단위라고 보면 될거 같고 각각의 state와 관장 영역이 있다. 가까이에선 Task Manager를 살펴보면 된다. 보면 각 task마다 각각 cpu와 ram resource를 확인할 수 있다. 그런데 여기서 터미널 하나를 죽여도 다른 상태는 별 영향이 없다. 이렇듯 테스크를 다루는 프로세서의 상태는 제각각 다르다. 이전에 잠깐 나왔던 context의 개념이 바로 그렇다. 이 context만 유지된다면 여러 task가 수행되어도 다 개별적으로 이뤄진다는 것이다. 다르게 생각해보면 이 테스크를 공유할 수 있게 하면 하나의 task에서 또다른 context를 만들 필요가 없다는 점이 있다. 여기서 멀티테스킹..
프로세서는 1초에 정말 많은 량의 instruction을 처리하고, 보통 컴퓨터의 성능을 측정할 때는 이 초당 instruction 처리 수를 따지며 이걸 Instruction Per Second (IPS)라고 한다. 한 인스트럭션을 처리하는데 하나의 분기가 소요된다고 해서 보통은 clock이라는 개념으로도 쓴다. 말에서 나온 것처럼 1초에 몇번의 인스트럭션을 처리하는지 알 수 있기 때문에 반대로 아주 간단한 인스트럭션을 처리하는 데 걸리는 시간을 측정하면 정확한 시간 측정도 가능해지는 것이다. 이건 프로세서의 입장에서 본 시간의 개념이고... 지난번 포스트에서 다룬 외부 장치를 통제하는 PIC의 IRQ 0번에는 이런 시간에 관한 설정을 다루는 부분이 달려있는데 이걸 Programmable Interva..
이제 Queue도 구현되었기 때문에 이걸 통해서 간단한 콘솔 쉘을 만드는 것이 15절의 목적이다. 일단 기본적인 쉘의 기능을 수행하기 위해서는 특정 키의 입력에 대한 반응(예를 들어 엔터를 치면 줄 바꿈이 된다던가 탭키를 눌렀을 때 간격이 늘어나는 등의 기능)을 줄 수 있어야 하고, 시스템에서 제공하는 자원에 대한 접근이 명령어를 통해서 이뤄질 수 있어야 한다. 일단 명령어를 수행하다 보면 변수의 갯수가 중요한 요소일 수 있기 때문에 이를 가변적으로 처리하기 위해서는 va_list 같은 가변 변수의 사용이 필요하다. 이 책에서는 5개의 명령어를 제공하고 각각의 기능을 한번씩 써봤다, - 잘못된 명령이 입력된 경우, 즉 입력값이 ShellCommandEntry에 들어가 있지 않은 경우에는 위와 같은 반응을..
전전 포스트에서도 이야기 했다시피 키보드 입력을 받을 때 인터럽트 방식을 적용하면 일일이 프로세서가 감시할 필요가 없기 때문에 효율성 측면에서 더 좋다고 했었다. 지난 포스트에서 다룬 인터럽트 핸들러를 이제 키보드 입력에 집어넣는 부분이다. 사실 인터럽트 방식에서도 생길 수 있는 문제 중 하나는 키보드 입력이 "언제" 들어왔는지를 알 수 없다는 것이다. 매번 말했다시피 키보드 입력이 들어올 때만 인터럽트가 걸리기 때문에 전체적인 테스크 상에서 입력이 들어온 시점은 인터럽트 발생 시점과 동일하고, 따라서 주기도 불규칙하다. 이와중에 입력받은 스캔코드 값을 알아야 전달할 수 있기 때문에 문제가 발생하는데 이 책에서 언급하는 방법은 바로 버퍼를 활용해서 값을 전달받는 방식이다. 키보드 핸들러를 통해서 키가 입..
지난 포스트에서 말한 인터럽트를 사용자가 정의할 수도 있지만 이걸 효율적으로 제어할 수 있는 장치가 바로 Programmable Interrupt Controller(PIC)이고, 여기서 나오는 출력에는 IRQ 몇번이라는 이름이 붙어있다. 보통 컴퓨터가 고장났을 때 오류정보속에 포함되어있는 IRQ에 대한 정보를 확인해보면 어느 부분에서 문제를 일으키는 지를 확인할 수 있다. 일일이 컴퓨터를 분해해보는게 아닌 것이다. 인터럽트나 예외를 처리하고 난 후에는 이전에 수행하던 상태로 돌아가야 하기 때문에 애초에 인터럽트에 진입할 때부터 그 때의 상태를 저장해야 하는데 이걸 context라고 한다. 그래서 초기 인터럽트 발생시에는 context를 저장하고 핸들러를 수행 후에 다시 context를 load 하는 일..
이전 포스트에서 언급했던 것처럼 시스템 자원이 계속 입력만을 감시하는 낭비를 막기 위해서 interrupt라는 개념을 도입했다, 간단하게 말하면 프로세서의 귀를 막고 직접적인 간섭이 있지 않는 한은 관여하지 않게끔 하는 내용이다. 이밖에도 Exception이라는 비슷한 개념도 있는데 이 차이는 발생하는 주체가 다르다는 것이다. Interrupt는 외부 장치나 소프트웨어의 간섭으로 인해 프로세서가 관여하는 형식이기에 주체가 당연히 프로세서가 아닌 외부 장치이겠지만, Exception은 프로세서가 오류가 발생했을 때가 알아서 처리되는 동작이기에 주체는 프로세서가 된다. 아무튼 이런 걸 다루는 것들을 handler라고 하는데 보통은 프로세서가 관여하기 전의 상태를 담고 있어서 interrupt나 Excepti..
이틀동안 삽질하다가 드디어 키보드 입력까지 왔다. Mint OS가 키보드 입력을 받는 방식은 일단은 기다리고 있다가 스캔코드가 들어오는 대로 뿌려주는 방식이다. 이렇게 받아오는 값이 스캔 코드, 흔히 말하는 ASCII 코드가 되며, 커널로 전달될 때도 우리가 입력하는 값에 대한 스캔 코드가 넘어오기 때문에 그걸로 출력을 하기 위해서는 따로 테이블이 존재해야 한다. 그래서 키보드 상에 있는 자판 중 88개의 경우에 대해서 테이블을 작성한 후에 그 결과를 보는 중이다. 장 보면 알겠지만 bochs 창 아래에는 각 Lock 자판도 표현이 되어 있으며, 거기에 대한 LED도 가상으로나마 구현된다. 지금 위의 이미지는 NumLock이 켜져 있는 상태이다. 나머지도 각각에 대한 Lock키가 활성화 되어 있는 상태이..
앞에서도 계속 나오다시피 모든 동작은 메모리 주소에 따라서 수행되고 이때문에 메모리 관리 방식이 OS에서는 중요시 여겨지는 요소 중 하나다. 메모리 관리 방식은 크게 Segmentation 방식과 Paging 방식으로 나눌 수 있는데 Paging으로 구현시에는 같은 물리메모리라도 다른 인자를 연결해서 프로그램을 로드할 수 있기에 공간을 조금더 효율적으로 사용할 수 있다. Segmentation에서 영역을 나누기 위해 Descriptor라는 개념을 사용하고 이를 구분하기 위해서 DescriptorTable이 있던 것처럼 Paging에서도 주소를 결합하기 위해서 Page Directory와 Page Table이 필요하다. 지금은 메모리를 통해서 프로그램을 로드하는 것이 아니기에 단순히 생성하고 초기화하는 과..
- Total
- Today
- Yesterday
- Expression Blend 4
- Policy Gradient
- Off-policy
- Gan
- dynamic programming
- DepthStream
- SketchFlow
- processing
- reward
- 강화학습
- Offline RL
- Kinect for windows
- Distribution
- 딥러닝
- TensorFlow Lite
- ColorStream
- Pipeline
- arduino
- ai
- PowerPoint
- RL
- windows 8
- 한빛미디어
- Windows Phone 7
- bias
- Kinect SDK
- 파이썬
- Kinect
- Variance
- End-To-End
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |