rw_semaphore阻塞I/O密集型线程

3

我在应用程序中追踪性能瓶颈时遇到了一些问题。我正在GPU上进行计算,并使用多个线程加载和准备数据。所有文件都存储在SSD上,但有时性能会急剧降低(vmstat显示读取速度从300MB/s降至30MB/s)。当我运行ps时,我注意到大多数工作线程经常被阻塞在call_rwsem_down_write_failedcall_rwsem_down_read_failed上。实际输出如下:

-     - user   Dl   47.4 -               call_rwsem_down_read_failed
-     - user   Rl   48.5 -               -
-     - user   Dl   48.5 -               call_rwsem_down_write_failed
-     - user   Dl   47.2 -               call_rwsem_down_read_failed
-     - user   Dl   46.8 -               call_rwsem_down_write_failed
-     - user   Dl   49.1 -               call_rwsem_down_write_failed
-     - user   Dl   46.8 -               call_rwsem_down_write_failed
-     - user   Dl   47.2 -               call_rwsem_down_write_failed
-     - user   Dl   46.9 -               call_rwsem_down_write_failed
-     - user   Dl   49.3 -               call_rwsem_down_read_failed
-     - user   Dl   47.2 -               call_rwsem_down_write_failed
-     - user   Dl   48.4 -               call_rwsem_down_write_failed

奇怪的是,这个应用程序使用Torch7和libpng来加载图片,但两者都没有使用rw_semaphore(我已经搜索了源代码)。此外,线程不执行任何写操作。
由于我找不到任何地方使用它们,我怀疑这一切都发生在某些系统调用中(可能是read?)。是否有任何方法可以检查使用这些信号量的位置并消除阻塞?
提前感谢!

1
我怀疑这一切都发生在某个系统调用中(能读取吗?)- 是的,几乎任何系统调用都可能使用rw_semaphores。但这是内核代码,所以你在用户空间库中找不到它。作为应用程序编写者,你很少想要深入内核。使用strace或类似工具来获取在用户空间代码中发生争用的位置。 - Tsyvarev
我尝试了strace,发现唯一的系统调用是openfstatreadmmapbrkclose。我不知道这些调用为什么需要rw_semaphore,所以我在这里提问 - 我不知道如何在没有这些知识的情况下改变我的代码,使其更高效。 - wesolyromek
1个回答

2
有没有办法检查这些信号量在哪里被使用了……?
只要你的内核已经适当地配置,你就可以在控制台上使用 系统请求 w - 显示阻塞(D状态)任务列表
echo w >/proc/sysrq-trigger
dmesg

查看调用堆栈跟踪。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接