Linux VM(重型多线程应用程序)的性能改进

Posted

技术标签:

【中文标题】Linux VM(重型多线程应用程序)的性能改进【英文标题】:Performance improvement on Linux VM(heavy multi threaded app) 【发布时间】:2018-04-20 09:16:16 【问题描述】:

您好,在对应用程序进行一些分析后,我得到以下内核调用堆栈,位于应用程序的顶部。其余执行的 CPU 使用率非常低(在 0.x - 2% 之间,绿色区域)。

Linux (VM VirtualBox) 上的代码 (C++) 时间设置为 hpet(可以在调用中看到)处理 100 TXN/秒的应用程序(5 个线程)(TCP/DB 写作...)调整 gettimeofday 的方法还是 Virtual Box 的管理程序真的很糟糕。 htop 上的 CPU 负载......在机器上约为 30-40%。 (4 核 i7 + 6GB RAM)

示例:128K 事件“cpu-clock”,事件计数(大约):32221750000 开销命令共享对象符号

14.52% app [kernel.kallsyms] [k] _raw_spin_unlock_irqrestore
    _raw_spin_unlock_irqrestore
        8.82% hrtimer_start_range_ns
            8.79% do_nanosleep
                hrtimer_nanosleep
                compat_sys_nanosleep
                sysenter_dispatch
        4.22% try_to_wake_up
        1.06% __wake_up_sync_key

**13.47% app [kernel.kallsyms] [k] read_hpet**
    read_hpet
    12.10% __getnstimeofday64
        getnstimeofday64
            10.28% do_gettimeofday
                compat_sys_gettimeofday
                sysenter_dispatch
            1.70% ktime_get_real
    1.36% ktime_get

11.67% app [kernel.kallsyms] [k] native_sched_clock
    native_sched_clock
        11.67% sched_clock
            local_clock
                9.92% tcp_transmit_skb
                    tcp_write_xmit
                    __tcp_push_pending_frames
                    tcp_push

这是其余的一些电话。这个应用程序很大,我不想添加所有性能数据,但这里有一个更大的 sn-p:

+   14.52%  app   [kernel.kallsyms]             [k] _raw_spin_unlock_irqrestore
+   13.47%  app   [kernel.kallsyms]             [k] read_hpet                  
+   11.67%  app   [kernel.kallsyms]             [k] native_sched_clock         
+    9.81%  app   [kernel.kallsyms]             [k] finish_task_switch               
+    1.25%  app   libc-2.17.so                  [.] __memcpy_ssse3                               
+    0.90%  app   libc-2.17.so                  [.] __memcmp_sse4_2            
+    0.85%  app   [kernel.kallsyms]             [k] __do_softirq     
     0.84%  app   app                        [.] list<var_entry>::find                     
+    0.81%  app   libc-2.17.so                  [.] __strlen_sse2_bsf              
+    0.66%  app   app                        [.] __x86.get_pc_thunk.bx          
+    0.63%  app   libclntsh.so.11.1             [.] kpuexec                        
+    0.51%  app   libclntsh.so.11.1             [.] ttcfour                        
     0.48%  app   app                        [.] str_base::is_null   

还有同一问题的 reddit 链接(可能是更好的文本格式)

https://www.reddit.com/r/AskProgramming/comments/8dm5mb/performance_improvement_on_linux_vmheavy_multi/

【问题讨论】:

因此您需要采取的下一步是创建一个最小示例。在这种情况下,它可能是一个简单的循环,只调用 getTimeOfDay 并在其中进行睡眠。然后,这将证明您在该函数中的高 CPU 时间是因为它很慢,而不是因为您在紧密循环中调用它。就目前情况而言,您可以运行 5 个线程来执行 while (1) getTimeOfDay();(如果这本身不是 UB) 情况并非如此......但我将通过添加更多应用程序层来更新我的初始性能跟踪。此外,创建一个最小的示例意味着缓存性能会受到影响,我的意思是它将超出现实世界的示例。我不是直接指责 gettimeofday 调用,因为我说过它可以是 Virtual Box 的管理程序 ... 或者你的线程有问题。如果您创建一个调用 getTimeOfDay 的单线程程序并测量其性能并且它没有问题;那么您知道您的问题与您的线程按照您的编辑建议将所有时间都花在自旋锁上这一事实有关。 Ehm ...如果您按照您所说的去做(单线程应用程序),您将进入缓存预测,它会尽可能快地进行缓存预测。问题是,这是一个处理巨大负载的现有应用程序,我的意思是您可以排除锁或无用的旋转。我正在寻求调整解决方案。如果你有什么可以帮忙的,那我听听,但我们不要浪费时间去指责。 好吧,您可以创建自己的函数,例如 my_gettimeofday(),它实际上会在每次调用时调用 gettimeofday(),例如第 10000 次调用,并在每次调用时重置本地静态原子计时器.在两次 gettimeofday() 调用之间,您可以根据自上次调用 gettimeofday() 以来的计时器经过的时间来计算一天中的时间。但是,再一次,计时器代码可能比 gettimeofday() 慢,直到你测试它才能知道。 【参考方案1】:

它是VBox的管理程序,它不能胜任任务:(。在KVM上的普通服务器上运行它之后一切都很好。

【讨论】:

我目前在我的 Java 应用程序中遇到_raw_spin_unlock_irqstore 高 CPU 使用率的相同问题。你有什么想法为什么它可以有这么高的 CPU 使用率?

以上是关于Linux VM(重型多线程应用程序)的性能改进的主要内容,如果未能解决你的问题,请参考以下文章

多线程递归程序c++

2021-06-11 aps计划在重型装备的运用

linux 最多支持多少个线程

基础第六篇:Linux操作系统线程库性能测试与分析

Linux 发展史与vm安装linux centos 6.9

如何使用异步 Web 请求进行多线程