【发布时间】:2021-11-29 18:55:29
【问题描述】:
我正在使用 libx264 库将视频数据压缩到... x264。
我使用默认设置让库根据需要创建尽可能多(少)的线程:
param.i_threads = X264_THREADS_AUTO;
这在我有 64 个处理器(2 个 CPU,每个 CPU 有 16 个内核和英特尔线程)的服务器上效果很好。它实际上将使用大约 5 个线程。
但是,在运行该软件的嵌入式计算机上,我只有 4 个 CPU。它是 Xeon,所以那里没有太多问题,但不知何故它会阻止 USB 端口正常工作。我们正在从那个 USB 端口接收数据,当 4 个 CPU 以大约 100% 的速度使用时,libx264 代码非常糟糕地接管了整个计算机。
我在想两种解决方案,使用 3 作为最大线程数:
param.i_threads = 3;
或者让那些 libx264 线程有一个(很多)更高的 nice 值,这样在该计算机上运行的其他东西就不会被阻塞(即 CPU 更好地共享;其他东西不使用太多 CPU,它通常低于10%)。
但是,我无法控制 libx264 库如何创建线程,并且想知道在调用创建线程的 libx264 函数之前更改 nice 值是否对我有用,因此这些线程使用它不错的价值,像这样:
nice(10);
...call libx264 functions...
nice(0);
使这些线程使用 +10 的良好值的意愿?从我在pthread_create() 手册页中可以看到,它并没有明确说明线程继承父线程的nice 值...
注意 1: 我知道这个问题不太可能是因为 USB 端口可能正在与视频采集卡争夺 DMA……如果是这种情况,我们'显然不会仅仅通过改变进程的优先级来解决任何问题。我想先试试那个软解决方案。
虽然我可以将 USB 端口移到另一台计算机上,但数据会通过网络传输,这很可能会出现类似的硬件冲突问题。
注意 2: 我不想重新编译 libx264 并更改该代码。这超出了我的项目范围。
【问题讨论】:
-
“想知道它是否可行”。当然,这可以通过尝试来回答或至少进行调查。运行代码,看看线程的nice值?
-
Niceness 继承自父进程/线程,AFAIK。考虑到它们的 TID(您可以在系统调用中将其用作 PID),您始终可以在它们启动后
renice(2)线程,提高它们的友好度。您甚至可以完全从进程外部执行此操作,手动使用top或htop或ps+renice(1),作为一次性实验,无需更改任何代码。 -
请记住,在没有 root 权限的情况下,您只能使事物 more nice,而不能将 nice 降为 0(niceness 越低,优先级越高)。因此,为了让一些线程更友好,您可以编写一个使用 nice(2) 的包装函数,然后对 x264 函数进行尾调用,这样父线程就不必改变自己的友好度。从该线程开始的任何更多线程 x264 将至少与此一样好。
-
回复:你的实际问题;我猜想让所有超线程保持忙碌可能会消耗大量内存带宽/缓存占用空间。仅让 x264 每个 物理 内核启动一个线程,但为 DMA 留出更多带宽,您可能不会看到吞吐量下降太多。以及在必要时为 CPU 密集型 USB 设备腾出内核。 (我怀疑下半部分中断处理程序的优先级甚至低于
nice(-19),但如果涉及其他用户空间进程,那么nice可能很重要..) -
你的问题的答案:“那会让那些线程使用一个不错的 +10 值吗?” 是 是。您可以通过编写一个简单的测试程序并运行它来确认这一点,使用
htop或任何其他工具来检查它的好坏。不知道这里还有什么要说的。进程/线程的好处是整个互联网都在谈论令人作呕的事情......
标签: c linux multithreading intel nice