OSTEP:程序上下文切换的开销

第六章:受限制直接执行/上下文切换

实验环境

由于该实验要求在单个CPU上运行两个进程并在他们两个UNIX管道,而书中介绍的sche_affinity()函数的具体调用不是很清楚,所以这里通过Docker的参数限制,创建了一个只使用宿主机一个CPU资源的容器进行实验。

单核Docker容器的创建

1
docker run -it -d --cpuset-cpus="0" --name=os ubuntu:latest

注:在以上环境中如果使用函数查询CPU核心数依旧可以发现为16或其他多核,但是在通过指令stress -c 4实际测试后,性能只会在宿主机的单一CPU核心上运行,不影响实验。但是如果在创建Docker容器的时候使用的是--cpus=1,由于负载均衡,并不能达到单核进行实验的目的。

测量思路

  1. 通过gettimeofday()增加时间戳函数,获取执行时间

  2. 创建10个管道,循环5次,每次循环的时候分别在两个管道之间反复通信,并输出上下文切换时间差

代码实现

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/time.h>

// 标记时间戳
uint64_t getTimeTick()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_usec;
}

int main()
{
// 创建十个管道用于读写测试
int fd[10][2];
for (int i = 0; i < 10; i++)
{
if (pipe(fd[i]) < 0)
{
perror("pipe");
exit(1);
}
}
char timeWrite[256], timeRead[256];
// 创建子进程
for (int i = 0; i < 9; i += 2)
{
int rc = fork();
switch (rc)
{
case -1: // error
perror("fork");
exit(EXIT_FAILURE);
case 0:
// 从管道一中读取数据,如果管道一中没有数据,则阻塞等待
read(fd[i][0], timeRead, sizeof(timeRead));
printf("Read - Write %d: %lu\n", i, getTimeTick() - atol(timeRead));
// 将时间写入管道二
sprintf(timeWrite, "%lu", getTimeTick());
write(fd[i + 1][1], timeWrite, sizeof(timeWrite));
// 从管道一中读取数据,并计算进程切换的总时间
exit(0);
default:
// 将时间写入管道一
sprintf(timeWrite, "%lu", getTimeTick());
write(fd[i][1], timeWrite, sizeof(timeWrite));
// 由于在执行完write之后会继续执行主进程,下方的read也会运行,因此最后结果中奇数进程的结果时间会比偶数进程的时间长,正确答案应该靠近偶数
// 从管道二读取数据,如果管道二中没有数据,则阻塞等待
read(fd[i + 1][0], timeRead, sizeof(timeRead));
printf("Read - Write %d: %lu\n", i + 1, getTimeTick() - atol(timeRead));
break;
}
}
return 0;
}

测量结果

1
2
3
4
5
6
7
8
9
10
Read - Write 0: 24
Read - Write 1: 7
Read - Write 2: 16
Read - Write 3: 6
Read - Write 4: 17
Read - Write 5: 7
Read - Write 6: 17
Read - Write 7: 6
Read - Write 8: 18
Read - Write 9: 9

结果差错

由于在执行完write之后会继续执行主进程,下方的read也会运行,因此最后结果中奇数进程的结果时间会比偶数进程的时间长,正确答案应该靠近偶数(已经在代码中用注释写明)。


OSTEP:程序上下文切换的开销
https://halc.top/p/4b65fa48
作者
HalcyonAzure
发布于
2022年3月25日
许可协议