Cent OS 6.3 上 usleep 的 CPU 使用率高

2023-12-15

我在 cent os 5.3 和 cent os 6.3 上编译以下代码:

#include <pthread.h>
#include <list>
#include <unistd.h>
#include <iostream>
using namespace std;
pthread_mutex_t _mutex;
pthread_spinlock_t spinlock;

list<int *> _task_list;

void * run(void*);
int main()
{
    int worker_num  = 3;
        pthread_t pids[worker_num];
        pthread_mutex_init(&_mutex, NULL);
        for (int worker_i = 0; worker_i < worker_num; ++worker_i)
        {
                pthread_create(&(pids[worker_i]), NULL, run, NULL);
        }
    sleep(14);
}


void *run(void * args)
{
        int *recved_info;
    long long start;
        while (true)
        {
            pthread_mutex_lock(&_mutex);
                if (_task_list.empty())
                {
                        recved_info = 0;
                }
                else
                {
                        recved_info = _task_list.front();
                        _task_list.pop_front();
                }
            pthread_mutex_unlock(&_mutex);

                if (recved_info == 0)
                {
                        int f = usleep(1);
            continue;
        }
    }
}

在5.3上运行时,你甚至找不到上面的进程,CPU使用率在0%左右。但在 Cent os 6.3 上,在 4 核 cpu 上使用 6 个线程时,效率约为 20%。

所以我检查 a.outtime and stace,结果大约是:

On 5.3:

real    0m14.003s
user    0m0.001s
sys     0m0.001s

On 6.3:

real    0m14.002s
user    0m1.484s
sys  0m1.160s

跟踪:

on 5.3:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 91.71    0.002997           0     14965           nanosleep
  8.29    0.000271         271         1           execve
  0.00    0.000000           0         5           read
  0.00    0.000000           0        10         4 open
  0.00    0.000000           0         6           close
  0.00    0.000000           0         4         4 stat
  0.00    0.000000           0         6           fstat
  0.00    0.000000           0        22           mmap
  0.00    0.000000           0        13           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         3           rt_sigaction
  0.00    0.000000           0         3           rt_sigprocmask
  0.00    0.000000           0         1         1 access
  0.00    0.000000           0         3           clone
  0.00    0.000000           0         1           uname
  0.00    0.000000           0         1           getrlimit
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0        38         4 futex
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         4           set_robust_list
------ ----------- ----------- --------- --------- ----------------
100.00    0.003268                 15092        13 total

on 6.3:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 99.99    1.372813          36     38219           nanosleep
  0.01    0.000104           0       409        43 futex
  0.00    0.000000           0         5           read
  0.00    0.000000           0         6           open
  0.00    0.000000           0         6           close
  0.00    0.000000           0         6           fstat
  0.00    0.000000           0        22           mmap
  0.00    0.000000           0        15           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         3           rt_sigaction
  0.00    0.000000           0         3           rt_sigprocmask
  0.00    0.000000           0         7         7 access
  0.00    0.000000           0         3           clone
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         1           getrlimit
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         4           set_robust_list
------ ----------- ----------- --------- --------- ----------------
100.00    1.372917                 38716        50 total

时间和strace结果不是同一个测试,所以数据有点不同。但我认为它可以展示一些东西。

我检查内核配置 CONFIG_HIGH_RES_TIMERS、CONFIG_HPET 和 CONFIG_HZ:

On 5.3:

$ cat /boot/config-`uname -r` |grep CONFIG_HIGH_RES_TIMERS
$ cat /boot/config-`uname -r` |grep CONFIG_HPET
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
CONFIG_HPET=y
# CONFIG_HPET_RTC_IRQ is not set
# CONFIG_HPET_MMAP is not set
$ cat /boot/config-`uname -r` |grep CONFIG_HZ
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
CONFIG_HZ_1000=y
CONFIG_HZ=1000

On 6.3:

$ cat /boot/config-`uname -r` |grep CONFIG_HIGH_RES_TIMERS
CONFIG_HIGH_RES_TIMERS=y
$ cat /boot/config-`uname -r` |grep CONFIG_HPET
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
CONFIG_HPET=y
CONFIG_HPET_MMAP=y
$ cat /boot/config-`uname -r` |grep CONFIG_HZ
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
CONFIG_HZ_1000=y
CONFIG_HZ=1000

事实上,我也在ARM和xubuntu13.04-amd64-desktop上尝试了arch上的代码,与cent os 6.3相同。

那么我该如何找出CPU使用率不同的原因呢?

它与内核配置有什么关系吗?


你是对的,这与内核配置有关。usleep(1)会尝试休眠一微秒。在高分辨率计时器出现之前,睡眠时间不可能少于一瞬间(在您的情况下 HZ=1000,所以 1 瞬间 == 1 毫秒)。

在没有这些高分辨率计时器的 CentOS 5.3 上,您将休眠 1 毫秒到 2 毫秒[1]。在具有这些计时器的 CentOS 6.3 上,您的睡眠时间接近一微秒。这就是您在此平台上使用更多 cpu 的原因:您只需多轮询任务列表 500-1000 次即可。

如果将代码更改为usleep(1000),CentOS 5.3 也会表现相同。 CentOS 6.3 的 cpu 时间将会减少,与 CentOS 5.3 上运行的程序大致相同

Linux 手册中有对此的完整讨论:运行man 7 time.

请注意,您的代码应使用条件变量,而不是按特定时间间隔轮询任务列表。这是一种更高效、更干净的方式来完成您正在做的事情。

另外,你的 main 应该真正加入线程,而不是仅仅休眠 14 秒。

[1] 有一个例外。如果您的应用程序在实时调度策略(SCHED_FIFO 或 SCHED_RR)下运行,它会忙等待而不是睡眠到接近正确的睡眠量。但默认情况下需要root权限

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Cent OS 6.3 上 usleep 的 CPU 使用率高 的相关文章

随机推荐

  • 通过 CSS 选择器选择两个已知元素之间的所有元素

    我有两个已定义 id 的元素 它们之间有任何 html 例如 div Hello div div Example div hr a href Example a div World div 是否有 CSS 选择器可以选择 d1 和 d2 之
  • HTTP 状态 500 - Servlet appServlet 的 Servlet.init() 引发异常

    我想尝试一个简单的程序 但出现以下错误 我正在使用 Eclipse Kelper 和 Tomcat 7 0 尝试了很多事情 但没有什么对我有用 HTTP Status 500 Servlet init for servlet appServ
  • Firebase 安全规则阻止写入 Firebase

    注 此问题已标记 polymer 因为 Polymer 库用于生成 Javascript 这个问题是关于处理 Firebase 安全性的两个不同但相关的问题 在尝试让 Firebase 安全规则发挥作用时 问题 1 和问题 2 似乎提出了相
  • Javascript 通过匹配字符串对数组进行排序

    我有一个包含地理位置代码结果的数组 我想按与我搜索过的术语最接近的匹配项对其进行排序 例子 搜索 Pizza Array Pizza Uno Pizzeria Uno Burgers and Pizzeria Cino Pizzeria 排
  • 如何绕过 Swagger-UI 的身份验证?

    如何从浏览器绕过 Swagger UI 的令牌身份验证 我可以通过 Postman 向 Swagger UI 发出请求 当我从浏览器发出请求时 我收到错误 因为它请求令牌 http localhost 8080 swagger ui ind
  • 如何使用所需的 BSTR* 参数正确调用 IDispatch::Invoke

    有很多关于如何使用 BSTR 参数调用 IDispatch Invoke 的示例 我将此与许多其他 SomeType 参数一起使用 但无论我尝试什么 我要么得到类型不匹配的HRESULT E OUTOFMEMORY 要么得到访问冲突 在我看
  • 为什么我不能简单地将安装的 Perl 模块复制到其他机器上?

    我对 Perl 很陌生 但对动态语言还不太熟悉 我对模块的管理如此不直接感到有点惊讶 Sure cpan X理论上确实有效 但我正在从三台不同的机器和操作系统上处理同一个项目 在工作中 在家里 在外部环境中进行测试 在工作中 Windows
  • 使用内容值的更新方法

    Helper public boolean mMessagesSent String ID int Data SQLiteDatabase db this getWritableDatabase ContentValues contentV
  • 调用非对象上的成员函数 num_rows()

    我正在使用 CodeIgniter 并且我想从数据库中的表中获取一些数据 在我的模型中 我有这个功能 public function fetch cours limit start element id element this gt db
  • 使用 Python 请求在请求之间设置新的 cookie

    我现在正在这样做 但在最后一行失败了TypeError expected string or buffer import requests from urllib parse import urlparse url some url s r
  • Rake 无法迁移

    C Users MEGHA bbbb gt rake db migrate rake aborted SyntaxError C Users MEGHA bbbb db migrate 20140402130040 create comme
  • Python zip 单个列表元素

    我有这个 t 1 2 3 4 5 6 11 22 33 44 55 66 并想要得到这个 1 4 11 44 2 5 22 55 3 6 33 66 如何以Pythonic方式做到这一点 使用星号 它可以解压参数列表 gt gt gt zi
  • 创建表时出错

    在 MySQL 终端上粘贴以下 MySQL 命令后 出现以下错误 此代码是我从项目的生产环境中获取的 我想根据生产环境的数据库更新本地数据库 mysql gt CREATE TABLE cityguide pointofinterest g
  • 我可以将自己的jsp页面导入到另一个jsp页面中吗?

    我已经使用 netbeans 准备了一个静态 html 页面 我可以将该页面导入到另一个页面中 以便不再重新编写代码 然后进行相应的更改吗 您可以使用以下方法将 JSP 页面合并到另一个页面中 include像这样的指令 或通过使用
  • 按日期从 iPhone 删除本地通知

    iPhone 上的 LocalNotification 是否有可能在某个日期加载 我的问题是我为通知创建了一个事件 但在创建后释放了该对象 或者我可以创建一个具有相同数据的新对象来删除我的通知吗 对不起我的英语不好 预定的本地通知将为您提供
  • PHP 简单乘法的舍入误差[重复]

    这个问题在这里已经有答案了 PHP 在使用时似乎舍入不正确 int 来转换变量 为什么 multiplier 100000000 value 0 01020637 echo int value multiplier Output 10206
  • Ruby 是否执行尾部调用优化?

    函数式语言导致使用递归来解决很多问题 因此许多语言执行尾调用优化 TCO TCO 导致从另一个函数 或本身 在这种情况下 此功能也称为尾递归消除 它是 TCO 的子集 调用函数 作为该函数的最后一步 不需要新的堆栈帧 这减少了开销和内存使用
  • 在后台线程中创建可冻结对象时发生资源泄漏

    在我的应用程序中 我创建Freezable后台 线程池 线程中的对象 冻结它们 然后在主线程上显示它们 一切正常 除了一段时间后 整个系统变得缓慢并且应用程序最终崩溃 我已经设法将问题减少到这一行 var temp new DrawingG
  • F# 默认情况下使用惰性求值吗?

    F 甚至有惰性求值吗 F 默认情况下不是惰性的 类似于 Haskell 但显式的惰性是可用的 看惰性计算在 MSDN 上
  • Cent OS 6.3 上 usleep 的 CPU 使用率高

    我在 cent os 5 3 和 cent os 6 3 上编译以下代码 include