答案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
当和max
(以及其他软件,如果你忘记了/dev/null
输出)开始在 和 之间疯狂切换时,这似乎非常明显。