什么可能导致我的程序在一段时间后不使用所有内核?

Posted

技术标签:

【中文标题】什么可能导致我的程序在一段时间后不使用所有内核?【英文标题】:What could cause my program to not use all cores after a while? 【发布时间】:2011-10-02 12:59:41 【问题描述】:

我编写了一个程序,可以从三个视频卡中捕获和显示视频。对于每一帧,我都会生成一个线程,将帧压缩为 Jpeg,然后将其放入队列中以写入磁盘。我还有其他线程从这些文件中读取并在自己的线程中对其进行解码。通常这工作正常,它是一个相当 CPU 密集型程序,使用所有六个 CPU 内核的 70-80%。但是过了一会儿,编码突然变慢了,程序无法足够快地处理视频并开始丢帧。如果我检查 CPU 利用率,我可以看到一个核心(通常是核心 5)不再做太多事情了。

发生这种情况时,我是否退出并重新启动我的程序并不重要。 CPU 5 的利用率仍然很低,程序会立即开始丢帧。删除所有保存的视频也没有任何效果。重新启动计算机是唯一有帮助的方法。哦,如果我将程序的亲和性设置为使用除半空闲核心之外的所有核心,它会一直工作,直到另一个核心发生同样的情况。这是我的设置:

AMD X6 1055T(Cool & Quiet OFF) GA-790FX-UD5 主板 4Gig RAM 非联动 1333Mhz' Blackmagic Decklink DUO 采集卡 (x2) Linux - Ubuntu x64 10.10 内核 2.6.32.29

我的应用使用:

libjpeg-turbo posix 线程 decklink api Qt 用 C/C++ 编写 动态链接的所有库

在我看来,Linux 在内核上调度线程的方式会出现某种问题。或者是否有某种方式我的程序可能会变得如此糟糕以至于重新启动程序无济于事?

感谢您的阅读,欢迎提出任何意见。我被困住了:)

【问题讨论】:

听起来你的磁盘访问遇到了 IO 瓶颈。 你能说出半空闲核心在做什么吗?也许它正在处理磁盘 I/O 或视频卡中断? @Useless 我不知道找出空闲核心在做什么的好方法。你有什么好的建议吗? @awoodland 这会导致我的 jpeg 编码变慢吗? (仅在 RAM 访问中) @Nioreh - 我以为你正在将结果写入磁盘?如果某些操作系统级别的写入缓冲区已满,则可能会看到诸如停止线程之类的行为。 【参考方案1】:

首先,请确保它不是您的程序 - 也许您遇到了一个复杂的并发错误,即使您的程序架构不太可能发生这种情况,并且重新启动内核会有所帮助。我发现,通常情况下,一个好方法是事后调试。用调试符号编译,当程序出现异常时用 -SEGV 终止程序,并用 gdb 检查核心转储。

【讨论】:

我会考虑这样做。我在调试方面不是很有经验,但也许现在是时候开始深入挖掘了:) 谢谢 @Nioreh :如果您找到答案,请更新。只是出于好奇;) @Nioreh:你能检查一下你的队列大小增长和任何多线程访问问题吗?如果设计不当,多线程环境中的队列也可能成为瓶颈。【参考方案2】:

当产生新的帧处理线程并将线程固定到该核心时,我会尝试选择核心循环 a。统计线程运行所需的时间。如果这实际上是 Linux 调度程序中的一个错误 - 您的线程将花费大致相同的时间在任何内核上运行。如果核心实际上正忙于其他事情 - 固定到该核心的线程将获得更少的 CPU 时间。

【讨论】:

以上是关于什么可能导致我的程序在一段时间后不使用所有内核?的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用任务集在一组独立的内核上运行多线程 Linux 程序会导致所有线程在一个内核上运行?

Python虚拟助手在一段代码后不继续运行,而1:

我的领域文件会在一段时间后自动清除所有数据

Android模拟器状态栏在一段时间后消失

拟合模型时,内核在一段时间后停止工作

c9由于连接方在一段时间后没有正确答复