文档章节

测试进程上下文切换时间

考拉睡
 考拉睡
发布于 2013/04/04 13:38
字数 851
阅读 293
收藏 0
测试Context Switch time(进程上下文切换时间) 
-------------------------------------------------- 
    创建两个进程(实时进程)并在它们之间传送一个令牌,如此往返传送一定的次数。其中一个进程在读取令牌时就会引起阻塞。另一个进程发送令牌后等待其返回时也处于阻塞状态。发送令牌带来的开销与上下文切换带来的开销相比,可以忽略不计。 (利用管道传递令牌) 


测试程序(1) 使用gettimeofday()获取当前时间 
--------------------------------------------------
 
C代码    收藏代码
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <sys/time.h>  
  4. #include <time.h>  
  5. #include <sched.h>  
  6. #include <sys/types.h>  
  7. #include <unistd.h>      //pipe()  
  8.   
  9. int main()  
  10. {  
  11.     int x, i, fd[2], p[2];  
  12.     char send    = 's';  
  13.     char receive;  
  14.     pipe(fd);  
  15.     pipe(p);  
  16.     struct timeval tv;  
  17.     struct sched_param param;  
  18.     param.sched_priority = 0;  
  19.   
  20.     while ((x = fork()) == -1);  
  21.     if (x==0) {  
  22.         sched_setscheduler(getpid(), SCHED_FIFO, &param);  
  23.         gettimeofday(&tv, NULL);  
  24.         printf("Before Context Switch Time %u us\n", tv.tv_usec);  
  25.         for (i = 0; i < 10000; i++) {  
  26.             read(fd[0], &receive, 1);  
  27.             write(p[1], &send, 1);  
  28.         }  
  29.         exit(0);  
  30.     }  
  31.     else {  
  32.         sched_setscheduler(getpid(), SCHED_FIFO, &param);  
  33.         for (i = 0; i < 10000; i++) {  
  34.             write(fd[1], &send, 1);  
  35.             read(p[0], &receive, 1);  
  36.         }  
  37.         gettimeofday(&tv, NULL);  
  38.         printf("After Context SWitch Time %u us\n", tv.tv_usec);  
  39.     }  
  40.     return 0;  
  41. }  



测试结果(进程切换时间不超过5us) 
-------------------------------------------------- 
Before Context Switch Time 617087 us 
After Context SWitch Time 702420 us 

702420us - 617087us = 85333 us 
85333us / 20000    = 4.26665 us 

进程切换时间为4.26665 us 

注: cpu MHz         : 2801.042 






测试程序(2) 使用rdtsc()获取当前时间 
--------------------------------------------------
 
C代码    收藏代码
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <sched.h>  
  4. #include <sys/types.h>  
  5. #include <unistd.h>  
  6.   
  7. long long rdtsc()  
  8. {  
  9.     __asm("rdtsc");  
  10. }  
  11.   
  12. int main()  
  13. {  
  14.     int x, i, fd[2], p[2];  
  15.     char send    = 's';  
  16.     char receive;  
  17.     pipe(fd);  
  18.     pipe(p);  
  19.     struct sched_param param;  
  20.     param.sched_priority = 0;  
  21.   
  22.     while ((x = fork()) == -1);  
  23.     if (x==0) {  
  24.         sched_setscheduler(getpid(), SCHED_FIFO, &param);  
  25.         printf("Before Context Switch Time %lld\n", rdtsc());  
  26.         for (i = 0; i < 10000; i++) {  
  27.             read(fd[0], &receive, 1);  
  28.             write(p[1], &send, 1);  
  29.         }  
  30.         exit(0);  
  31.     }  
  32.     else {  
  33.         sched_setscheduler(getpid(), SCHED_FIFO, &param);  
  34.         for (i = 0; i < 10000; i++) {  
  35.             write(fd[1], &send, 1);  
  36.             read(p[0], &receive, 1);  
  37.         }  
  38.         printf("After Context Switch Time %lld\n", rdtsc());  
  39.     }  
  40.     return 0;  
  41. }  


测试结果(进程切换时间不超过5us) 
-------------------------------------------------- 
Before Context Switch Time 16208184381648 
After Context Switch Time 16208424333213 

16208424333213 - 16208184381648 = 239951565(clock cycle) 
239951565      * 0.357009998 ns = 85665107.74074687 ns 
85665107.74074687 ns / 20000    = 4283.255387037 ns = 4.283255387037 us 






注: cpu MHz         : 2801.042 
--------------------------------------------- 
2 801 042 000Hz 
clock cycle = 1 000 000 000 ns / 2 801 042 000 = 0.357009998ns 

查看CPU性能参数 
cat /proc/cpuinfo
 








测试程序(3) 可直接获得进程上下文切换时间 
--------------------------------------------------
 
C代码    收藏代码
  1. #include <stdio.h>  
  2. #include <stdlib.h>        //drand48()  
  3. #include <sched.h>  
  4. #include <sys/types.h>  
  5. #include <unistd.h>  
  6. #include <sys/time.h>      //gettimeofday()  
  7. #include <time.h>  
  8.   
  9.   
  10. typedef unsigned long long u64;  
  11. double clockCycleTimeS,clockRateHZ;  
  12.   
  13. /* 获取当前时间,返回秒 */  
  14. double second() {  
  15.     struct timeval tv;  
  16.     gettimeofday(&tv,0);  
  17.     return tv.tv_sec + 1e-6 * tv.tv_usec;  
  18. }  
  19.   
  20. /* 获取当前时间,返回clock cycle */  
  21. u64 rdtsc() {  
  22.     u64 tsc;  
  23.     __asm__ __volatile__("rdtsc" : "=A" (tsc));  
  24.     return tsc;  
  25. }  
  26.   
  27. /* 睡眠us微秒 */  
  28. void selectsleep(unsigned us) {  
  29.     struct timeval tv;  
  30.     tv.tv_sec = 0;  
  31.     tv.tv_usec = us;  
  32.     select(0, 0, 0, 0, &tv);  
  33. }  
  34.   
  35. /* 计算当前CPU的工作频率 */  
  36. void calibrate() {  
  37.     double sumx = 0;  
  38.     double sumy = 0;  
  39.     double sumxx = 0;  
  40.     double sumxy = 0;  
  41.     double slope;  
  42.     const unsigned n = 30;  
  43.     unsigned i;  
  44.   
  45.     for (i=0; i<n; i++) {  
  46.         double breal,real,ticks;  
  47.         u64 bticks;  
  48.   
  49.         breal = second();  
  50.         bticks = rdtsc();  
  51.         selectsleep((unsigned)(10000 + drand48() * 200000));  
  52.         ticks = rdtsc() - bticks;  
  53.         real = second() - breal;  
  54.   
  55.         sumx += real;  
  56.         sumxx += real * real;  
  57.         sumxy += real * ticks;  
  58.         sumy += ticks;  
  59.     }  
  60.     slope = ( (sumxy - (sumx*sumy) / n) /  
  61.               (sumxx - (sumx*sumx) / n) );  
  62.     clockRateHZ = slope;  
  63.     clockCycleTimeS = 1.0 / slope;  
  64.     printf("%3.3f MHz\n", clockRateHZ*1e-6);  
  65. }  
  66.   
  67. int main()  
  68. {  
  69.     calibrate();  
  70.   
  71.     int x, i, p1[2], p2[2], time[2];  
  72.     char send    = 's';  
  73.     char receive;  
  74.     u64 old_time;  
  75.     pipe(p1);  
  76.     pipe(p2);  
  77.     pipe(time);  
  78.     struct sched_param param;     
  79.     param.sched_priority = 0;     
  80.   
  81.     while ((x = fork()) == -1);  
  82.     if (x==0)  
  83.     {  
  84.         sched_setscheduler(getpid(), SCHED_FIFO, &param);  
  85.         old_time = rdtsc();  
  86.         write(time[1], &old_time, sizeof(old_time));  
  87.         for (i = 0; i < 10000; i++) {  
  88.             read(p1[0], &receive, 1);  
  89.             write(p2[1], &send, 1);  
  90.         }  
  91.         exit(0);  
  92.     }  
  93.     else  
  94.     {  
  95.         u64 new_time;  
  96.         sched_setscheduler(getpid(), SCHED_FIFO, &param);  
  97.         for (i = 0; i < 10000; i++) {  
  98.             write(p1[1], &send, 1);  
  99.             read(p2[0], &receive, 1);  
  100.         }  
  101.         new_time = rdtsc();  
  102.         read(time[0], &old_time, sizeof(old_time));  
  103.         printf("Latency time = %3.3f us\n",  
  104.                 1e6 * (new_time - old_time) * clockCycleTimeS / 20000);  
  105.     }  
  106.     return 0;  
  107. }  




测试结果(Linux-2.6.21 + RealTime Patch) 
-------------------------------------------------- 
2801.226 MHz 
Latency time = 8.129 us



原文连接:http://ocelot1985-163-com.iteye.com/blog/1029949

© 著作权归作者所有

考拉睡
粉丝 3
博文 20
码字总数 22770
作品 0
昌平
私信 提问
如何测量上下文切换时间

LINUX查看指定进程的Context Switch上下文切换:pidstat Context Switch(CS)上下文切换是cpu性能中的一个重要指标,context switch过高会导致CPU像个搬运工,频繁在寄存器和运行队列之间奔波...

一贱书生
2016/11/25
288
0
[转载] [嵌入式开发]Linux性能分析——上下文切换

标签 PostgreSQL , Linux , 上下文切换 背景 原文 http://www.cnblogs.com/pheye/p/4830058.html 一、从一个问题说起 相信很多人在玩手机还是PC时,都曾碰到过这样一种情况,安装的软件多了系...

德哥
2018/04/18
0
0
Linux vmstat命令实战详解

vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况。这个命令是我查看Linux/Unix最喜爱的命令...

Wall_Z
2014/06/27
86
0
【转】Linux vmstat命令实战详解

文章转自:http://www.cnblogs.com/ggjucheng/archive/2012/01/05/2312625.html#2533669 vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使...

张玉涛
2012/11/30
0
0
vmstat命令之linux性能分析

系统情况 [root@ceshiji ~]# cat /etc/redhat-releaseCentOS Linux release 7.2.1511 (Core)[root@ceshiji ~]# iostat -cLinux 3.10.0-327.36.3.el7.x8664 (ceshiji) 2018年01月02日 x8664 ......

品鉴初心
2018/01/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

数据安全管理:RSA算法,签名验签流程详解

本文源码:GitHub·点这里 || GitEE·点这里 一、RSA算法简介 1、加密解密 RSA加密是一种非对称加密,在公开密钥加密和电子商业中RSA被广泛使用。可以在不直接传递密钥的情况下,完成加解密操...

知了一笑
42分钟前
5
0
Podman 使用指南

> 原文链接:Podman 使用指南 Podman 原来是 CRI-O 项目的一部分,后来被分离成一个单独的项目叫 libpod。Podman 的使用体验和 Docker 类似,不同的是 Podman 没有 daemon。以前使用 Docker...

米开朗基杨
今天
6
0
拯救 项目经理个人时间的5个技巧

优秀的项目经理都有一个共同点,那就是良好的时间管理能力。专业的项目经理会确保他们的时间投入富有成效,尽可能避免时间浪费。 时间管理叫做GTD,即Getting Things Done——“把事情做完”...

Airship
今天
7
0
LNMP环境介绍,Mariadb安装,服务管理,mariadb安装3

LNMP环境介绍 Nginx 处理的请求有两种,分为 静态与动态 图片,js,css,视频,音频,flash 等都是静态请求,这些数据都不是保存在数据库里面的 动态请求一般来说,需要的数据是在数据库里面...

doomcat
今天
3
0
前端技术之:Prisma Demo服务部署过程记录

安装前提条件: 1、已经安装了docker运行环境 2、以下命令执行记录发生在MackBook环境 3、已经安装了PostgreSQL(我使用的是11版本) 4、Node开发运行环境可以正常工作 首先需要通过Node包管...

popgis
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部