프로세스의 가상 주소 공간에는 1GB의 커널 공간이 포함됩니다.
이제 이 1GB 커널 공간이 커널 관련 데이터 및 코드(IDT(Interrupt Descriptor Table) 포함)를 가리킨다고 가정합니다.
이제 프로세스가 CPU에 의해 실행되고 있고 해당 프로세스가 시스템 호출을 한다고 가정합니다(인터럽트 0x80
(int 0x80
)를 트리거함). 무슨 일이 일어날지는 CPU가 IDT로 가서 인터럽트 번호와 연관된 인터럽트 핸들러를 실행한다는 것입니다 0x80
.
이제 CPU는 현재 프로세스에 머물며 현재 프로세스의 커널 공간에서 인터럽트 핸들러를 실행합니까(그래서 컨텍스트 전환이 발생하지 않습니까)?
답변1
int 0x80
i386이 다른 아키텍처를 사용할 수 있다고 가정합니다 .예를 들어 syscall
amd64의 경우. 시스템 호출이 이루어질 때마다 컨텍스트 전환이 발생한다면 이는 많은 시스템 호출을 생성하는 프로그램을 실행할 때 쉽게 볼 수 있어야 합니다. 운 좋게도 그런 프로그램이 있습니다.
bits 64
section .text
global _start
_start: mov r9,9551615
mov rax,1 ; sys_write
mov rdi,1 ; stdout
mov rsi,letter
mov rdx,1 ; length
_again: syscall
dec r9
jnz _again
mov rax,60 ; sys_exit
mov rdi,0 ; exit code
syscall
section .data
letter: db "a"
64비트 Linux 시스템에서 컴파일하고 실행하면 다음과 같은 결과 perf
가 나타납니다 .
$ nasm -f elf64 -g -F dwarf -o max.o max.asm
$ ld -o max max.o
$ sudo perf stat ./max > /dev/null 2> perf.log
$ grep context perf.log
88 context-switches # 0.051 K/sec
$
프로세스는 88번의 컨텍스트 전환만 수행했습니다. 커널이 프로세스의 컨텍스트에 있을 때마다 컨텍스트 전환이 발생했다면 9551615번의 컨텍스트 전환을 볼 수 있습니다.
지금! 컨텍스트 전환으로 인한 시스템 오류를 확인하려면 위 명령을 아래에 실행하십시오.strace
$ strace -c ./max
...
이미 다른 창에서 실행 중입니다 vmstat 1
...
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 896 333928 2132 3124628 0 0 0 0 74 98 0 0 100 0 0
0 0 896 333896 2132 3124628 0 0 0 0 89 103 0 0 100 0 0
0 0 896 333896 2132 3124628 0 0 0 0 65 85 0 0 100 0 0
0 0 896 333896 2132 3124628 0 0 0 0 67 83 0 0 100 0 0
2 0 896 333756 2132 3124628 0 0 0 0 21460 529902 10 29 61 0 0
3 0 896 333832 2132 3124628 0 0 0 0 23690 652506 13 32 55 0 0
1 0 896 333832 2132 3124628 0 0 0 0 27574 673152 11 33 55 0 0
0 0 896 333768 2132 3124628 0 0 0 0 24351 650723 11 30 59 0 0
strace
이는 and max
(및 출력을 잊어버린 경우 다른 소프트웨어 /dev/null
)가 및 사이에서 미친 듯이 전환하기 시작할 때 매우 분명해 보입니다.