sched_yield 标记为顶级热点

在使用 Vtune 分析程序时,我发现 libc 函数 sched_yield 被标记为重要的热点。

现在看到这个函数大致负责上下文切换;我说粗略是因为这是我第一次遇到这个函数,所以我的理解是它运行在操作系统调度器内部,为改变活动线程提供支持。

sched_yield 作为主要热点对我的程序意味着什么?这是否意味着我创建的线程多于应有的数量,而操作系统正试图处理连续的上下文切换?

对于这种情况,有什么补救措施?也许采用更集中的线程池来避免过度生成线程?

接下来我应该分析什么?在这种情况下是否有“典型的”后续步骤? Vtune 已经建议对“线程”进行分析。

d459462473 回答:sched_yield 标记为顶级热点

sched_yield 作为主要热点对我的程序意味着什么?

在 Linux 上,sched_yield 不一定切换到另一个线程来执行。如果没有准备好在同一 CPU 上运行的线程,内核不会取消调度调用线程。最后一部分很重要,因为内核不会在此调用时重新安排 CPU 之间准备运行的线程。这是一种设计权衡,因为 sched_yield 应该是内核的低成本提示。

由于 sched_yield 可能会立即返回而不执行任何操作,因此您的代码可能会围绕此调用进行繁忙循环,这在您的个人资料中看起来像是一个热点。您的代码只是在 sched_yield 周围循环了很多次,没有做太多其他事情。这种旋转会消耗大量 CPU 周期,而这些周期可用于系统上运行的其他线程和应用程序。

对于这种情况有什么补救措施?

这在很大程度上取决于您的用例。当您愿意浪费一些 CPU 周期以换取更好的延迟时,使用 sched_yield 可能是可以接受的。你必须意识到这个决定,即便如此,我还是建议对不同的解决方案进行基准测试,并使用适当的线程阻塞。 Linux 线程调度器非常高效,因此阻塞和唤醒线程并不像在其他一些系统上那样昂贵。

通常 sched_yield 用于自定义自旋锁算法。我建议用 pthread 组件替换它们,特别是 pthread_cond_t,它允许正确阻塞和唤醒线程。如果您使用的是 C++,则标准库中有等价物(例如 std::condition_variable)。在其他情况下,可能值得探索其他阻塞 API,例如 selectepoll。确切的解决方案取决于您的用例。

本文链接:https://www.f2er.com/16455.html

大家都在问