답변:
스레드 스위치와 프로세스 스위치의 주요 차이점은 스레드 스위치 동안 가상 메모리 공간이 동일하게 유지되는 반면 프로세스 스위치 동안에는 그렇지 않다는 것입니다. 두 유형 모두 컨텍스트 전환을 수행하기 위해 운영 체제 커널에 제어권을 넘겨주는 것이 포함됩니다. 레지스터를 전환하는 비용과 함께 OS 커널을 전환하는 프로세스는 컨텍스트 전환을 수행하는 가장 큰 고정 비용입니다.
더 모호한 비용은 컨텍스트 스위치가 프로세서 캐싱 메커니즘을 망친다는 것입니다. 기본적으로 컨텍스트 전환시 프로세서가 캐시에서 "기억"하는 모든 메모리 주소는 사실상 쓸모 없게됩니다. 여기서 한 가지 큰 차이점은 가상 메모리 공간을 변경할 때 프로세서의 TLB (번역 조회 버퍼) 또는 이와 동등한 기능이 플러시되어 잠시 동안 메모리 액세스 비용이 훨씬 더 많이 든다는 것입니다. 이것은 스레드 전환 중에는 발생하지 않습니다.
프로세스 컨텍스트 전환에는 메모리 주소 공간 전환이 포함됩니다. 여기에는 메모리 주소, 매핑, 페이지 테이블 및 커널 리소스가 포함되며 비교적 비용이 많이 드는 작업입니다. 일부 아키텍처에서는 주소 공간에서 공유 할 수없는 다양한 프로세서 캐시를 플러시하는 것을 의미하기도합니다. 예를 들어 x86은 TLB를 플러시해야하고 일부 ARM 프로세서는 L1 캐시 전체를 플러시해야합니다!
스레드 전환은 동일한 프로세스에서 한 스레드에서 다른 스레드로 컨텍스트를 전환하는 것입니다 (프로세스간에 스레드에서 스레드로 전환하는 것은 프로세스 전환 일뿐입니다). 프로세서 상태 전환 (예 : 프로그램 카운터 및 레지스터 내용)은 일반적으로 매우 효율적입니다.
우선 운영 체제는 나가는 스레드가없는 경우 커널 모드에서 나가는 스레드를 가져옵니다. 왜냐하면 스레드 전환은 커널 모드에서 실행되는 스레드간에 만 수행 될 수 있기 때문입니다. 그런 다음 스케줄러가 호출되어 전환을 수행 할 스레드에 대한 결정을 내립니다. 결정이 내려지면 커널은 CPU (CPU 레지스터)에있는 스레드 컨텍스트의 일부를 메모리의 전용 위치 (종종 나가는 스레드의 커널 스택 맨 위에 있음)에 저장합니다. 그런 다음 커널은 나가는 스레드의 커널 스택에서 들어오는 스레드의 커널 스택으로 전환을 수행합니다. 그 후 커널은 이전에 저장된 수신 스레드의 컨텍스트를 메모리에서 CPU 레지스터로로드합니다. 마지막으로 제어권을 사용자 모드로 되돌 리지만 새 스레드의 사용자 모드로 되돌립니다. OS에서 들어오는 스레드가 실행되는 것으로 판단한 경우또 다른 프로세스는 커널이 하나의 추가 단계를 수행합니다. 새로운 활성 가상 주소 공간을 설정합니다.
두 시나리오의 주요 비용은 캐시 오염과 관련이 있습니다. 대부분의 경우 나가는 스레드가 사용하는 작업 집합은 들어오는 스레드가 사용하는 작업 집합과 크게 다릅니다. 결과적으로 들어오는 스레드는 캐시 미스의 눈사태와 함께 수명을 시작하여 캐시에서 오래되고 쓸모없는 데이터를 플러시하고 메모리에서 새 데이터를로드합니다. TLB (CPU에있는 Translation Look Aside Buffer)도 마찬가지입니다. 가상 주소 공간을 재설정하는 경우 (스레드가 다른 프로세스에서 실행 됨) 가상 주소 공간을 재설정하면 전체 TLB가 플러시되기 때문에 패널티가 더 심합니다. 도새 스레드가 실제로 몇 개의 새 항목 만로드해야하는 경우. 결과적으로 새 스레드는 많은 TLB 누락과 빈번한 페이지 이동으로 시간 퀀텀을 시작합니다. 스레드 전환의 직접 비용도 무시할 수 없으며 (~ 250 ~ 1500-2000 사이클까지) CPU 복잡성, 스레드 상태 및 실제로 사용하는 레지스터 세트에 따라 달라집니다.
추신 : 컨텍스트 전환 오버 헤드에 대한 좋은 게시물 : http://blog.tsunanet.net/2010/11/how-long-does-it-take-to-make-context.html
스레드 컨텍스트 전환은 실행 컨텍스트 (레지스터, 스택 포인터, 프로그램 카운터)를 변경해야하지만 프로세스 컨텍스트 전환처럼 주소 공간을 변경할 필요는 없습니다. 주소 공간, 더 많은 메모리 액세스 (페이징, 세분화 등)를 전환 할 때 추가 비용이 발생하며 새 프로세스를 시작하거나 종료 할 때 TLB를 플러시해야합니다.