免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: 涩兔子
打印 上一主题 下一主题

[C] [求助]貌似得到的cpu使用率有问题 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2008-03-25 16:24 |只看该作者
原帖由 涩兔子 于 2008-3-25 16:18 发表
恩,谢谢版主,我去LOU LOU getstat的函数;

我心里想:是不是http://bbs.chinaunix.net/archiver/?tid-629524.html 讨论的是Linux kernel 2.4之前的,而2.6之后,/proc/stat的参数有变化的;

盼望有人给 ...

我贴出来的那个是我们现在用的,不过好像也不是很准确,跟top出来的不太一样,不过也差不多。

论坛徽章:
0
12 [报告]
发表于 2008-03-25 16:28 |只看该作者
恩,所以,我使用2个线程,会时不时地去调整CPU使用率,可是,现在获得CPU使用率都不准确,所以,多线程那块儿就没有继续往下写了;

我的get_cpu_usage的功能实际上和getstat类似,貌似;

我继续google一下,谢谢版主,经常看到你热心的回复

论坛徽章:
0
13 [报告]
发表于 2008-03-25 16:39 |只看该作者
sunmoom推荐了LKML里的一个测试用例:


  1. #if 0

  2. Hi Ingo and all,

  3. When I was executing massive interactive processes, I found that some of them
  4. occupy CPU time and the others hardly run.

  5. It seems that some of processes which occupy CPU time always has max effective
  6. prio (default+5) and the others have max - 1. What happen here is...

  7. 1. If there are moderate number of max interactive processes, they can be
  8.     re-inserted into active queue without falling down its priority again and
  9.     again.
  10. 2. In this case, the others seldom run, and can't get max effective priority
  11.     at next exhausting because scheduler considers them to sleep too long.
  12. 3. Goto 1, OOPS!

  13. Unfortunately I haven't been able to make the patch resolving this problem
  14. yet. Any idea?

  15. I also attach the test program which easily recreates this problem.

  16. Test program flow:

  17.   1. First process starts child proesses and wait for 5 minutes.
  18.   2. Each child process executes "work 8 msec and sleep 1 msec" loop
  19.      continuously.
  20.   3. After 3 minits have passed, each child processes prints the # of loops
  21.      which executed.

  22. What expected:

  23.   Each child processes execute nearly equal # of loops.

  24. Test environment:

  25.   - kernel:                 2.6.20(*1)
  26.   - # of CPUs:                 1 or 2
  27.   - # of child processes:  200 or 400
  28.   - nice value:            0 or 20(*2)

  29. *1) I confirmed that 2.6.21-rc5 has no change regarding this problem.
  30. *2) If a process have nice 20, scheduler never regards it as interactive.

  31. Test results:

  32. -----------+----------------+------+------------------------------------
  33. # of CPUs | # of processes | nice |              result
  34. -----------+----------------+------+------------------------------------
  35.            |                |   20 | looks good
  36.    1(i386) |                +------+------------------------------------
  37.            |                |    0 | 4 processes occupy 98% of CPU time
  38. -----------+            200 +------+------------------------------------
  39.            |                |   20 | looks good
  40.            |                +------+------------------------------------
  41.            |                |    0 | 8 processes occupy 72% of CPU time
  42.    2(ia64) +----------------+------+------------------------------------
  43.            |            400 |   20 | looks good
  44.            |                +------+------------------------------------
  45.            |                |    0 | 8 processes occupy 98% of CPU time
  46. -----------+----------------+------+------------------------------------

  47. FYI. 2.6.21-rc3-mm1 (enabling RSDL scheduler) works fine in the all casees :-)

  48. Thanks,

  49. Satoru

  50. -------------------------------------------------------------------------------
  51. #endif
  52. /*
  53. * massive_intr - run @nproc interactive processes and print the number of
  54. *                  loops(*1) each process executes in @runtime secs.
  55. *
  56. *                  *1) "work 8 msec and sleep 1msec" loop
  57. *
  58. *        Usage:  massive_intr <nproc> <runtime>
  59. *
  60. *                 @nproc:   number of processes
  61. *                 @runtime: execute time[sec]
  62. *
  63. *        ex) If you want to run 300 processes for 5 mins, issue the
  64. *            command as follows:
  65. *
  66. *                $ massive_intr 300 300
  67. *
  68. *        How to build:
  69. *
  70. *                cc -o massive_intr massive_intr.c -lrt
  71. *
  72. *
  73. *  Copyright (C) 2007  Satoru Takeuchi <[email]takeuchi_satoru@jp.fujitsu.com[/email]>
  74. *
  75. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  76. *
  77. *  This program is free software; you can redistribute it and/or modify
  78. *  it under the terms of the GNU General Public License as published by
  79. *  the Free Software Foundation; either version 2 of the License, or (at
  80. *  your option) any later version.
  81. *
  82. *  This program is distributed in the hope that it will be useful, but
  83. *  WITHOUT ANY WARRANTY; without even the implied warranty of
  84. *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  85. *  General Public License for more details.
  86. *
  87. *  You should have received a copy of the GNU General Public License along
  88. *  with this program; if not, write to the Free Software Foundation, Inc.,
  89. *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  90. *
  91. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  92. */

  93. #include <sys/time.h>
  94. #include <sys/types.h>
  95. #include <sys/stat.h>
  96. #include <sys/mman.h>
  97. #include <sys/wait.h>
  98. #include <fcntl.h>
  99. #include <unistd.h>
  100. #include <semaphore.h>
  101. #include <stdio.h>
  102. #include <stdlib.h>
  103. #include <time.h>
  104. #include <string.h>
  105. #include <errno.h>
  106. #include <err.h>

  107. #define WORK_MSECS        8
  108. #define SLEEP_MSECS        1

  109. #define MAX_PROC        1024
  110. #define SAMPLE_COUNT        1000000000
  111. #define USECS_PER_SEC        1000000
  112. #define USECS_PER_MSEC        1000
  113. #define NSECS_PER_MSEC        1000000
  114. #define SHMEMSIZE        4096

  115. static const char *shmname = "/sched_interactive_shmem";
  116. static void *shmem;
  117. static sem_t *printsem;
  118. static int nproc;
  119. static int runtime;
  120. static int fd;
  121. static time_t *first;
  122. static pid_t pid[MAX_PROC];
  123. static int return_code;

  124. static void cleanup_resources(void)
  125. {
  126.         if (sem_destroy(printsem) < 0)
  127.                 warn("sem_destroy() failed");
  128.         if (munmap(shmem, SHMEMSIZE) < 0)
  129.                 warn("munmap() failed");
  130.         if (close(fd) < 0)
  131.                 warn("close() failed");
  132. }       

  133. static void abnormal_exit(void)
  134. {
  135.         if (kill(getppid(), SIGUSR2) < 0)
  136.                 err(EXIT_FAILURE, "kill() failed");
  137. }

  138. static void sighandler(int signo)
  139. {
  140. }

  141. static void sighandler2(int signo)
  142. {
  143.         return_code = EXIT_FAILURE;
  144. }

  145. static void loopfnc(int nloop)
  146. {
  147.         int i;
  148.         for (i = 0; i < nloop; i++)
  149.                 ;
  150. }

  151. static int loop_per_msec(void)
  152. {
  153.         struct timeval tv[2];
  154.         int before, after;

  155.         if (gettimeofday(&tv[0], NULL) < 0)
  156.                 return -1;
  157.         loopfnc(SAMPLE_COUNT);
  158.         if (gettimeofday(&tv[1], NULL) < 0)
  159.                 return -1;
  160.         before = tv[0].tv_sec*USECS_PER_SEC+tv[0].tv_usec;
  161.         after = tv[1].tv_sec*USECS_PER_SEC+tv[1].tv_usec;

  162.         return SAMPLE_COUNT/(after - before)*USECS_PER_MSEC;
  163. }

  164. static void *test_job(void *arg)
  165. {
  166.         int l = (int)arg;
  167.         int count = 0;
  168.         time_t current;
  169.         sigset_t sigset;
  170.         struct sigaction sa;
  171.         struct timespec ts = { 0, NSECS_PER_MSEC*SLEEP_MSECS};

  172.         sa.sa_handler = sighandler;
  173.         if (sigemptyset(&sa.sa_mask) < 0) {
  174.                 warn("sigemptyset() failed");
  175.                 abnormal_exit();
  176.         }
  177.         sa.sa_flags = 0;
  178.         if (sigaction(SIGUSR1, &sa, NULL) < 0) {
  179.                 warn("sigaction() failed");
  180.                 abnormal_exit();
  181.         }
  182.         if (sigemptyset(&sigset) < 0) {
  183.                 warn("sigfillset() failed");
  184.                 abnormal_exit();
  185.         }
  186.         sigsuspend(&sigset);
  187.         if (errno != EINTR) {
  188.                 warn("sigsuspend() failed");
  189.                 abnormal_exit();
  190.         }
  191.         /* main loop */
  192.         do {
  193.                 loopfnc(WORK_MSECS*l);
  194.                 if (nanosleep(&ts, NULL) < 0) {
  195.                         warn("nanosleep() failed");
  196.                         abnormal_exit();
  197.                 }
  198.                 count++;
  199.                 if (time(&current) == -1) {
  200.                         warn("time() failed");
  201.                         abnormal_exit();
  202.                 }
  203.         } while (difftime(current, *first) < runtime);

  204.         if (sem_wait(printsem) < 0) {
  205.                 warn("sem_wait() failed");
  206.                 abnormal_exit();
  207.         }
  208.         printf("%06d\t%08d\n", getpid(), count);
  209.         if (sem_post(printsem) < 0) {
  210.                 warn("sem_post() failed");
  211.                 abnormal_exit();
  212.         }
  213.         exit(EXIT_SUCCESS);
  214. }

  215. static void usage(void)
  216. {
  217.         fprintf(stderr,
  218.                 "Usage : massive_intr <nproc> <runtime>\n"
  219.                 "\t\tnproc  : number of processes\n"
  220.                 "\t\truntime   : execute time[sec]\n");
  221.         exit(EXIT_FAILURE);
  222. }

  223. int main(int argc, char **argv)
  224. {
  225.         int i, j;
  226.         int status;
  227.         sigset_t sigset;
  228.         struct sigaction sa;
  229.         int c;

  230.         if (argc != 3)
  231.                 usage();

  232.         nproc = strtol(argv[1], NULL, 10);
  233.         if (errno || nproc < 1 || nproc > MAX_PROC)
  234.                 err(EXIT_FAILURE, "invalid multinum");
  235.         runtime = strtol(argv[2], NULL, 10);
  236.         if (errno || runtime <= 0)
  237.                 err(EXIT_FAILURE, "invalid runtime");

  238.         sa.sa_handler = sighandler2;
  239.         if (sigemptyset(&sa.sa_mask) < 0)
  240.                 err(EXIT_FAILURE, "sigemptyset() failed");
  241.         sa.sa_flags = 0;
  242.         if (sigaction(SIGUSR2, &sa, NULL) < 0)
  243.                 err(EXIT_FAILURE, "sigaction() failed");
  244.         if (sigemptyset(&sigset) < 0)
  245.                 err(EXIT_FAILURE, "sigemptyset() failed");
  246.         if (sigaddset(&sigset, SIGUSR1) < 0)
  247.                 err(EXIT_FAILURE, "sigaddset() failed");
  248.         if (sigaddset(&sigset, SIGUSR2) < 0)
  249.                 err(EXIT_FAILURE, "sigaddset() failed");
  250.         if (sigprocmask(SIG_BLOCK, &sigset, NULL) < 0)
  251.                 err(EXIT_FAILURE, "sigprocmask() failed");

  252.         /* setup shared memory */
  253.         if ((fd = shm_open(shmname, O_CREAT | O_RDWR, 0644)) < 0)
  254.                 err(EXIT_FAILURE, "shm_open() failed");
  255.         if (shm_unlink(shmname) < 0) {
  256.                 warn("shm_unlink() failed");
  257.                 goto err_close;
  258.         }
  259.         if (ftruncate(fd, SHMEMSIZE) < 0) {
  260.                 warn("ftruncate() failed");
  261.                 goto err_close;
  262.         }
  263.         shmem = mmap(NULL, SHMEMSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  264.         if (shmem == (void *)-1) {
  265.                 warn("mmap() failed");
  266.                 goto err_unmap;
  267.         }
  268.         printsem = shmem;
  269.         first = shmem + sizeof(*printsem);
  270.        
  271.         /* initialize semaphore */
  272.         if ((sem_init(printsem, 1, 1)) < 0) {
  273.                 warn("sem_init() failed");
  274.                 goto err_unmap;
  275.         }

  276.         if ((c = loop_per_msec()) < 0) {
  277.                 fprintf(stderr, "loop_per_msec() failed\n");
  278.                 goto err_sem;
  279.         }

  280.         for (i = 0; i < nproc; i++) {
  281.                 pid[i] = fork();
  282.                 if (pid[i] == -1) {
  283.                         warn("fork() failed\n");
  284.                         for (j = 0; j < i; j++)
  285.                                 if (kill(pid[j], SIGKILL) < 0)
  286.                                         warn("kill() failed");
  287.                         goto err_sem;
  288.                 }
  289.                 if (pid[i] == 0)
  290.                         test_job((void *)c);
  291.         }

  292.         if (sigemptyset(&sigset) < 0) {
  293.                 warn("sigemptyset() failed");
  294.                 goto err_proc;
  295.         }
  296.         if (sigaddset(&sigset, SIGUSR2) < 0) {
  297.                 warn("sigaddset() failed");
  298.                 goto err_proc;
  299.         }
  300.         if (sigprocmask(SIG_UNBLOCK, &sigset, NULL) < 0) {
  301.                 warn("sigprocmask() failed");
  302.                 goto err_proc;
  303.         }
  304.         if (time(first) < 0) {
  305.                 warn("time() failed");
  306.                 goto err_proc;
  307.         }
  308.         if ((kill(0, SIGUSR1)) == -1) {
  309.                 warn("kill() failed");
  310.                 goto err_proc;
  311.         }
  312.         for (i = 0; i < nproc; i++) {
  313.                 if (wait(&status) < 0) {
  314.                         warn("wait() failed");
  315.                         goto err_proc;
  316.                 }
  317.         }
  318.         cleanup_resources();
  319.         exit(return_code);
  320. err_proc:
  321.         for (i = 0; i < nproc; i++)
  322.                 if (kill(pid[i], SIGKILL) < 0)
  323.                         if (errno != ESRCH)
  324.                                 warn("kill() failed");
  325. err_sem:
  326.         if (sem_destroy(printsem) < 0)
  327.                 warn("sem_destroy() failed");
  328. err_unmap:
  329.         if (munmap(shmem, SHMEMSIZE) < 0)
  330.                 warn("munmap() failed");
  331. err_close:
  332.         if (close(fd) < 0)
  333.                 warn("close() failed");       
  334.         exit(EXIT_FAILURE);
  335. }
复制代码


sunmoom咬一口

论坛徽章:
0
14 [报告]
发表于 2008-03-26 07:56 |只看该作者
sunmoom同学的这个是通过调用进程,改变CPU使用率的测试用例,如何得到CPU使用率,还需要我继续Google正确的公式

论坛徽章:
0
15 [报告]
发表于 2008-03-26 08:26 |只看该作者
原帖由 涩兔子 于 2008-3-25 10:41 发表
最近在看《编程之美》这本书,是电子工业出版社broadview发行的,里面有msra的一道面试题:

1. 如何通过命令行参数,让cpu的使用率保持在任意位置,如90%?

2. 如何让cpu的使用率表现为一条正xuan曲线? ...

知道为什么打不出“弦”字么?因为你读音错了

论坛徽章:
0
16 [报告]
发表于 2008-03-26 08:46 |只看该作者
啊,我还以为是scim的词库问题

论坛徽章:
0
17 [报告]
发表于 2008-03-26 15:06 |只看该作者
kern.cp_time不就可以了吗???

top.c上面不是很清楚的吗???

论坛徽章:
0
18 [报告]
发表于 2008-03-26 15:30 |只看该作者
有道理,应该看看top的源代码,何苦自己写

论坛徽章:
0
19 [报告]
发表于 2008-03-27 10:10 |只看该作者
恩,我还是觉得应该自己写,即便写的没有busybox的top.c那么好,因为《编程之美》中就强调“注意细微末节”的东东;

在项目中可以大量使用开源的优秀库,但是自己修炼,我还是想坚持能深入多少就深入多少
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP