본문 바로가기
  • AI (Artificial Intelligence)
Skills/Unix, Linux

context switching

by 로샤스 2014. 3. 31.

오늘날 우리가 사용하는 컴퓨터는 동시에 단 한 개의 명령어만을 처리할 수 있다. 하지만, 이 부분의 처리 속도는 매우 빠르기 때문에 순간 적으로 여러 개의 명령어를 처리하는 것처럼 보이게 되는데, 우리가 개발한 프로그램 역시 매우 빠른 속도로 처리된다. 때문에 두 가지 이상의 작업이 거의 동시에 발생되고 처리 되어지게 할 수 있다.

이렇게 작업을 병렬로 처리하는 것은 그 만큼 작업 시간이 줄어드는 것이므로 효율은 높아지게 된다.

우리가 구성할 네트워크는 매우 많은 패킷들을 순간적으로 처리해주어야 한다. 때문에 병렬 처리가 필수적이라 할 수
  있는데, 쓰레드라는 개념을 사용하여 이 것을 구현할 수 있다. 


■ Thread란?

- 하나의 작업 프로세스를 진행시키는 단위라고 이해하면 된다. 우리가 프로그램 하나를 만들 때 그 프로그램은 main을 갖고 있으며, 프로그램dms main에서부터 시작한다. 이 때 O/S는 실행될 프로그램에 쓰레드를 하나 할당하고, 그 스레드는 main함수를 실행하게 된다. 이렇게 실행된 프로그램에는 시스템으로부터 기본적으로 하나의 쓰레드가 주어지는데,이 것을 메인 쓰레드(Main thread)라고 한다.


■ Thread의 효율성
 

- 우리가 만드는 응용프로그램은 기본적으로 하나의 쓰레드를 할당 받아 작업을 진행한다. 때문에, 우리가 사용하는 Windows O/S는 이미 여러 개의 쓰레드가 동작하고 있는 것이다. 1 개의 CPU에서는 동시에 1개의 연산만이 가능하다고하였다. 하지만 그 처리속도는 매우 빠르기 때문에, 여러 개의 쓰레드를 순차적으로 처리하게 되면 거의 동시에 처리되어 지는 것으로 보여지게 되며, 이러한 방법으로 O/S는 우리에게 멀티 테스킹(Multitasking)을 지원할 수 있는 것이다.

 하나의 쓰레드가 시작되었다고 해서 그 쓰레드가 끝날 때 까지 연속된 작업을 진행하는 것이 아니다. O/S는 스레드 나가 한번에 진행할 수 있는 단위를 정하고 각 쓰레드들의 작업을 조금씩 진행시키는 병렬 처리를 한다.

 이렇게 병렬로 작업되는 쓰레드를 우리는 응용 프로그램에서 임의로 생성하고 작업을 할당할 수 있다. 즉, 우리의 프로그램이 내부에서 작업을 병렬로 처리할 수 있다는 의미이다.

 예를 들어, 한 서버에 두개의 클라이언트가 접속하였다고 하자. 클라이언트 들은 서로 작업 요청을 서버에 하게 되는데, 만일 서버가 메인 쓰레드만으로 모든 작업을 처리하려 한다면, 클라이언트로부터 들어오는 패킷을 쌓아놓고 순차적으로 읽어 들여 처리하고 다시 통보해주어야 한다.

  만일 여기에서 쓰레드를 더 생성하여 네트워크 작업과 내부 연산 작업을 병렬로 처리한다면 그만큼 처리 속도를 높일 수있을 것이다.


1. Server에 단일 Thread를 적용한 경우

Main Thread에서 모든 일들을 다 수행하고 있어서 순차적으로 읽어서 처리하고 다시 통보하므로, 속도가 느리고 비효율적이다.

2. Server에 다중 Thread를 적용한 경우

Accept Thread와 Worker Thread를 따로 두어서 Server의 일을 각각 분담하여 처리하고 있다.

 
각각의 Thread는 서로 다른 임무를 전문적으로 수행하고 있으므로, 처리속도도 빠를뿐아니라 효율도 올라갔다.
 
 
단, 너무 많은 Thread의 생성은 오히려 Server의 속도에 영향을 준다.
 
뱃사공이 많으면 배가 산으로 간다는 말과 비슷하다고 보면 된다.
 
 
 
■ Context Switching

- 쓰레드는 O/S에서의 기본적인 스케줄링 단위이다. 그리고 이러한 쓰레드를 O/S는 여러 개를 관리하면서 우리에게 멀티 태스킹을 가능하게 해준다. 하지만 앞서 일반적인 CPU는 한번에 한가지 명령만을 계산할 수 있다고 하였다.
 
 단지 여러 쓰레드의 순차적인 관리를 통해 거의 동시에 진행하게끔 한다고 하였는데, 이러한 관리를 위해서 쓰레드를 O/S에서 관리할 수 있는 기본적인 정보가 있어야 한다.
 
 쓰레드는 레지스터(Register Set), 커널 스택(Kernel Stack), 사용자 스택 등의 여러 정보를 갖고 있는데, 이러한 정보들을 Context라고 한다. Context들은 쓰레드가 작업을 진행하는 동안 작업에 대한 정보를 보관하고 있으며, 다른 쓰레드로작업 순서가 넘어갈 때 저장된다.
 O/S는 쓰레드 하나의 작업을 진행하기 위해 그 쓰레드의 Context를 읽어오며, 다시 다른 쓰레드로 작업을 변경할 때 이전 쓰레드의 Context를 저장하고 다시 진행할 쓰레드의 Context를 읽어오는 작업을 반복하게된다.

  이처럼 한 쓰레드에서 다른 쓰레드로 작업을 넘기는 과정을 Context Switching이라고 한다.

 우리의 응용 프로그램 차원에서 보면, Context Switching이라는 작업은 아주 미묘하고 작은 단위이다. 그 속도 또한 무시해도 될 만큼 빠르기 때문에 우리는 그다지 신경을 쓰지 않아도 프로그램은 아주 잘 동작할 것이다.
 
  하지만, 이렇게 처리해야 할 쓰레드의 개수가 매우 많다면 어떻게 될까? Windows O/S를 사용할 때 많은 프로그램들을 띄워놓고 작업하면 속도가 상당히 떨어짐을 느낄 수 있는데, 이 것은 작업해야 할 쓰레드가 많아짐에 따라 Context Switching이 매우 빈번하게 발생하며, 다시 차례가 돌아오기까지의 시간이 더 소비되기 때문이다.
 이처럼 Context Switching 작업은 매우 미묘할지라도 멀티 쓰레딩을 해야 하는 상황에서는 쓰레드의 개수에 신경을 써 주어야 한다. 병렬처리로 인해 작업 속도를 증가시킬 수는 있겠지만, 개수가 너무 많아지게 된다면 오히려 역효과를 가져올 수도 있으므로 신경써서 작업하고 성능 테스트를 꼭 해보길 바란다.
 
 테스트라함은 작업관리자를 띄워서 성능을 봤을때 CPU의 사용률을 보면 알 수가 있다. Server를 만들어서 CPU사용률을 체크하는 습관을 가지자..
 
  Ex)
 
  while( 1 )
  {
         if( count == 0 )                // Sleep(1)을 걸어주지 않으면 CPU의 사용률은 100%이다.
             Sleep( 1 );
  }
 
- 위의 코드는 WorkerThread의 일부분을 단적인 예로 보여진 부분이다. 여기서 접속한 User가 아무도 없을 경우 미친듯이 while문을 돌게 된다. 그러면 CPU의 사용률이 100%을 보이지만, User가 아무도 없을시에 Sleep(1)을 걸어주면, CPU의 사용률이 10%이하로 내려감을 볼 수가 있다.



====================================================
http://blog.naver.com/pys3710?Redirect=Log&logNo=40037685354

▲ RTAI task와 LINUX task간의 context switching time 시간 분석

 

 


1번 파형 (청  색) : rt_timer_handler() in sched_up.c 진입시 toggle  

2번 파형 (하늘색) : rt_set_timer_match_reg() in rtai_timer.h의 while()안에서 toggle

3번 파형 (보라색) : dispatch_irq() in rtai.c 시작 set, 끝날때 clear

4번 파형 (녹  색) : servo PWM task 진입시 set, rt_task_wait_period()전에 clear


-파형 설명

  위의 3번 파형을 보면 원래 일어나야 되는 시점에서 timer interrupt dispatch가 일어나지않은것을 확인할수 있다. timer interrupt dispatch가 일어나기 바로 전에는 linux의 작업을 수행하게 되는데 이때 어떤 원인에 의해서 정해진 timer가 제 시간에 일어나지 않게 된다. 이것으로 인해서 4번 파형의 task는 물론 1번도 제 시간에 발생하지 않은 것을 알수 있다. 이 상황의 원인에 대해서는 linux와 RTAI 간의 context switching 시간이 일반적인 상황보다 길어져서 나온 현상이라고 생각하는데 context switching시에는 모든 인터럽트를 금지 시키기 때문에 context switching 하는 시간에 지정된 timer 인터럽트가 발생하지 못하는 것이다. 이 부분에 대해서는 좀 더 연구를 해 볼 필요가 있다.


-파형으로 얻을수 있는 결과

-RTAI task와 linux task 간의 context switching 시간으로 인해 4us 정도의 오차가 발생 할수 있다.



===================================================

http://blog.naver.com/sunbust79?Redirect=Log&logNo=70017029039

Chap 4. 프로세스

 

① 문맥 (Context)

  프로세스의 중지 시점에서 프로세스의 실행에 필요한 모든 정보와 환경들이 저장되어야 하고 속개 시에는 그 내용이 복원되어야 하는데 이렇게 중지 시에 저장되고 속개시에 복원되는 프로세스의 실행 정보를 프로세스의 문맥 (Context)라고 한다.


② 프로세스의 문맥(Context) 구성

 - 사용자 수준의 프로세스 문맥

• 텍스트 영역 : 프로그램 코드 부분

• 데이터 영역 : 프로그램 광역 자료 부분

• 스택 영역 : 프로그램의 실행 시간 스택 부분

 - 커널 수준의 프로세스 문맥

• 중앙처리기 범용 레지스터의 내용 : 일반적 계산을 위해 활용되는 레지스터들의 내용

• 중앙처리기 특수 레지스터의 내용 : 프로세스의 수행 위치를 나타내는 프로그램의 계수기 (Program counter), 스택 포인터 레지스터, 중앙처리기 상태 레지스터 등.

• 각종 자원 활용 정보

• 프로세스에 대한 각종 정보


③ Context switching (or Preemption)

 CPU를 한 프로세스에서 다른 프로세스로 넘기는 작업


④ 프로세스의 상태

 (1) 신규 : 프로세스가 생성되고 있다.

 (2) 준비 : 프로세스가 중앙처리기의 할당을 기다리고 있다.

 (3) 실행 : 프로세스의 명령이 중앙처리기에 의해 수행되고 있다.

 (4) 대기 : 프로세스가 어떤 사건이 발생하기를 기다리고 있다.  (ex. DISK I/O, Interrupt)

 (5) 종료 : 프로세스의 실행이 종료



[그림 4.1] 프로세스의 상태



[용어 정리]

■ ready queue (ready list) - 준비 상태에 있는 다수의 프로세스들의 프로세스 제어 블록들을 모아 유지하는 리스트

■ time slice - 커널이 프로세스의 CPU를 회수하기 위한 방법으로 일반적으로 일정한 시간이 지나면 CPU를 회수하는 방식

■ 스케줄링 - 준비 리스트에 속한 프로세스는 각각 중앙처리기 할당을 위한 우선순위를 가지며 스케줄러는 항상 우선순위가 가장 높은 프로세스에게 중앙처리기를 할당

■ Process가 CPU를 회수 당하거나 반납하는 경우

 (1) 주어진 타임 슬라이스가 다 소진된 경우 - 중앙처리기를 회수당함 (준비 상태로 전이)

 (2) DISK I/O 등으로 인하여 타임 슬라이스가 소진되기 이전에 커널 내부에서 스스로 CPU 반환 (대기 상태로 전이)


 

■ 프로세스의 실행 상태 세분

 (1) 사용자 모드 실행 (user mode running)

 - 사용자 프로세스의 텍스트 영역의 코드가 실행. 라이브러리 함수의 실행도 포함.

  기존 라이브러리 함수는 프로그램이 적재될 때, 사용자 프로세스의 텍스트 영역에 포함된다. 기존 라이브러리 함수는 프로그램이 적재될 때, 사용자 프로세스의 텍스트 영역에 포함된 것이므로 사용자가 작성한 코드와 함께 사용자 모드 실행에 속한다.

 (2) 커널 모드 실행 (kernel mode running)

 - 프로세스가 실행 중에 메모리에 상주하는 커널의 시스템 함수를 호출하였거나 하드웨어 인터럽트가 발생하여 커널 안의 코드가 수행될 때, 프로세스는 커널 모드 실행 상태에 있다고 한다.

 

 

 

 

 

 

출처 : http://blog.naver.com/kirba518?Redirect=Log&logNo=150016939294

 

 

 

 

댓글