【发布时间】:2011-08-01 08:54:46
【问题描述】:
我试图通过设置后台线程来加速一段代码来解决一个特定的任务。当需要解决我的任务时,我想唤醒这些线程,完成工作并再次阻止它们等待下一个任务。任务总是一样的。
我尝试使用条件变量(以及需要与它们一起使用的互斥锁),但我最终降低了我的代码速度,而不是加快了它的速度;主要是因为调用所有需要的函数都非常昂贵 (pthread_cond_wait/pthread_cond_signal/pthread_mutex_lock/pthread_mutex_unlock)。
使用线程池(我也没有)没有意义,因为它是一个过于通用的构造;在这里,我只想解决我的具体任务。根据实现,我还会为队列支付性能损失。
您对不使用mutex 或con_var 的快速唤醒有什么建议吗?
我正在考虑设置线程,例如读取atomic variable 的计时器;如果变量设置为 1,线程将完成这项工作;如果设置为 0,它们将进入睡眠状态几微秒(我会从微秒睡眠开始,因为我想避免使用可能对 CPU 来说太贵的spinlocks)。你怎么看待这件事?任何建议都非常感谢。
我正在使用 Linux、gcc、C 和 C++。
【问题讨论】:
-
如果您的性能要求对于现有的互斥锁/条件变量方法来说过于极端,那么您已经到了需要消耗一点 CPU 旋转以完成更多工作的阶段,然后再重新使用互斥体/条件变量。微秒睡眠可能无法按您预期的那样工作:如果您的进程没有被取消调度,那么 CPU 无论如何都不会得到其他工作,如果是这样,您的延迟可能会飙升。
-
嗨托尼。我有一台多核 NUMA 机器。在这种情况下我不应该进行任何上下文切换,这是真的吗?我在没有任何特定设置或配置的情况下创建线程...您认为需要任何特殊设置来避免上下文切换吗?
-
@Abruzzo:有很多因素,主要是调度逻辑随着 Linux 内核版本的变化而改变。但是,一般来说,如果你告诉调度程序你无事可做并且它有一些东西在等待,我不会打赌它会让你留在身边(如果你的延迟时间显然是时间片内的更好机会)。通过任何认真的调整,聪明的钱都花在使用您的实际硬件、编译器、任务大小、争用率、数据流、内核版本等来实施替代方案和基准测试。
-
如果任务适合,我会提出使用内部状态机的无锁算法。
-
@Blagovest 你能详细说明一下吗?您的意思是围绕保持状态的变量进行while循环吗?我不明白如何将它们用于我的问题,即让我的线程对某些事件真正“反应”,并告诉他们尽快开始执行我的任务。
标签: c++ c multithreading performance atomic