面试 - 如何让应用程序CPU使用率50%
在分析二叉树最大距离问题时,搜索购买了《编程之美》,该书最前面谈到实现一个应用 占用CPU 50%问题。
1 我的解答
使用rdtsc/gettimeofday查询时间,并控制休眠和cpu占用百分比,最终达成目的。添加 adjust微调循环体本身的CPU占用,实际测试观察意义不大。多核下设置affinity绑定CPU, 可以提高稳定性,示例代码未添加。
代码如下:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/time.h> union rdtsc_union { unsigned long v64; struct { unsigned int low32; unsigned int high32; }; }; static __always_inline unsigned long rdtsc_ordered(void) { union rdtsc_union ru; asm volatile("mfence\n\tlfence\n\t" ::: "memory"); asm volatile("rdtsc" : "=a" (ru.low32), "=d" (ru.high32)); return ru.v64; } int main(int argc, char *argv[argc]) { int ratio = 50, idx; unsigned long rs, interval, interval_10ms, adjust; volatile int op_dummy = 0; if (argc > 1) ratio = atoi(argv[1]); if (ratio < 0 || ratio > 100) { fprintf(stderr, "invalid ratio(%d), reset to 50\n", ratio); ratio = 50; } // benchmark rs = rdtsc_ordered(); usleep(1000*10); // 10 millseconds interval_10ms = rdtsc_ordered() - rs; // optional adjust result for precising rs = rdtsc_ordered(); for (idx = 0; idx < 100; ++idx) { interval = rdtsc_ordered() - rs; if (idx > ratio) { struct timeval tv; gettimeofday(&tv, NULL); // fake syscall rdtsc_ordered(); } } // // 100 for os syscall, so call time adjust = (rdtsc_ordered() - rs)*10000*1000/interval_10ms/ratio; printf("interval_10ms=%lu, adjust=%lu, press Ctrl+c exit\n", interval_10ms, adjust); while (1) { interval = rdtsc_ordered() - rs; if (interval < interval_10ms*ratio) { ++op_dummy; } else { usleep(1000*10*(100-ratio) + adjust); rs = rdtsc_ordered(); } } return 0; }
GCC编译gcc -Wall -o cpuratio cpuratio.c测试,基本CPU占用在49.5%~50.5%之间。 传递参数设置不同占用比:
yanyg@t440:~/org/h/code$ gcc cpu-ratio.c -Wall -o cpu-ratio yanyg@t440:~/org/h/code$ ./a.out interval_10ms=29143618, adjust=228, press Ctrl+c exit ^C yanyg@t440:~$ top top output capture: 12023 yanyg 20 0 4172 652 576 S 50.2 0.0 0:03.02 cpu-ratio yanyg@t440:~/org/h/code$ ./cpu-ratio 80 interval_10ms=29217598, adjust=262, press Ctrl+c exit ^C yanyg@t440:~$ top top output capture: 12059 yanyg 20 0 4172 740 664 R 80.1 0.0 0:12.41 cpu-ratio
2 References
- 编程之美 - CPU曲线
- http://tianshu.xyz/blog/108/