【操作系统导论】第六章作业:测量系统调用和上下文切换的成本(LINUX系统)

1. 测量系统调用成本


使用书上给出的方法,重复调用一个简单的系统调用(执行0字节的读取)100000次,使用gettimeofday()函数测量总时间,再除以1e5,即可得到单次系统调用较为精确的时间成本,c代码如下:

//p1.c
#include <stdio.h>
#include <sys/time.h>
#include <fcntl.h>

int main() {
    int fd = open("./cpu.c", O_RDONLY|O_CREAT);
    if (fd == -1) {
        fprintf(stderr, "open failed");
        exit(1);
    }
    struct timeval start, end;
    char buf[10];
    gettimeofday(&start, NULL);
    for (int i = 0; i < 1e5; ++i) read(fd, (void*)buf, 0);
    gettimeofday(&end, NULL);
    printf("The time cost of system call is %lf us\n", (double)(end.tv_usec - start.tv_usec) / 1e5);
    close(fd);
    return 0;
}

编译p1.c文件:

gcc -o p1 p1.c -Wall

执行p1,打印输出结果为:

The time cost of system call is 0.079230 us

2.测量上下文切换成本


创建两个管道,两个进程。让进程1从管道1中读数据、向管道2中写数据;让进程2向管道1中写数据、从管道2中读数据。触发进程切换的机制是,利用管道通信,若管道中此时没有数据,进程仍从该管道中读取数据,那么该进程将会被阻塞,调度器从就绪进程队列中选择一个进程进行运行。利用Linux上的sched_setaffinity()函数,可以使得进程绑定到特定的处理器上,从而确保在测量操作系统在同一个处理器上切换上下文的成本。

#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main() {
    int pi1[2], pi2[2];
    char buf1[30], buf2[30];
    int p1, p2;
    struct timeval start, end;
    if ((p1 = pipe(pi1) < 0) || (p2 = pipe(pi2) < 0)) { //创建管道
        fprintf(stderr, "pipe failed");
        exit(1);
    }
    int rc = fork(); //创建子进程
    cpu_set_t mask;
    CPU_ZERO(&mask); //初始化set集(可用cpu集),置为空
    CPU_SET(1, &mask); //向可用cpu集中添加1
    for (int i = 0; i < 10; ++i) {
        if (rc < 0) {
            fprintf(stderr, "fork failed");
            exit(1);
        } else if (rc == 0) {
            if (sched_setaffinity(0, sizeof(mask), &mask) == -1) { //进程绑定到1号处理器
                fprintf(stderr, "Set CPU affinity failed");
                exit(1);
            }
            read(pi1[0], buf1, 25);
            gettimeofday(&end, NULL);
            printf("%ld\n", end.tv_usec - atol(buf1));
            gettimeofday(&start, NULL);
            sprintf(buf2, "%ld", start.tv_usec);
            write(pi2[1], buf2, 25);
        } else {
            if (sched_setaffinity(0, sizeof(mask), &mask) == -1) { //进程绑定到1号处理器
                fprintf(stderr, "Set CPU affinity failed");
                exit(1);
            }
            gettimeofday(&start, NULL);
            sprintf(buf1, "%ld", start.tv_usec);
            write(pi1[1], buf1, 25);
            read(pi2[0], buf2, 25);
            gettimeofday(&end, NULL);
            printf("%ld\n", end.tv_usec - atol(buf2));
        }
    }
    return 0;
}

编译并执行,打印输出结果为:

158
4
3
1
1
2
1
8
2
1
1
2
1
1
3
3
2
1
2
74

取最小值,即上下文切换成本需要1us左右的时间。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
操作系统导论》是一本关于操作系统基本概念和原理的教材。操作系统是计算机系统中最核心的软件之一,它管理和控制计算机硬件资源,并提供给用户和应用程序一个简单易用、高效稳定的接口。 《操作系统导论》主要内容包括操作系统的历史、发展背景,以及操作系统的基本概念、功能和特性等。通过对操作系统的研究,读者能够了解操作系统的架构和组成,掌握操作系统的重要原理和算法,并能够利用这些知识进行操作系统的设计和开发。 在《操作系统导论》中,读者将深入学习操作系统的各个模块,比如进程管理、内存管理、文件系统等。通过对这些模块的学习,读者能够理解操作系统的核心功能,并能够掌握操作系统的基本工作原理。此外,书中还介绍了操作系统的各种经典算法和策略,如调度算法、页面置换算法等,这些算法是实现操作系统功能的基础。 除了基本概念和原理外,《操作系统导论》还涵盖了一些研究热点和前沿技术,如分布式系统、虚拟化技术和云计算等。通过深入了解这些新领域的内容,读者可以了解到操作系统在不同领域的应用和发展趋势。 总之,《操作系统导论》是一本系统介绍操作系统的教材,内容丰富、深入浅出,适合计算机科学与技术相关专业的学生和从业人员阅读使用。通过学习这本书,读者能够全面了解操作系统的基本概念和原理,提高操作系统的设计和开发能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值