我的应用程序包含几个延迟临界线程,这些线程“自旋”,即永不阻塞。这样的线程预计将占用100%的一个CPU核心。然而,现代操作系统似乎经常将线程从一个内核转移到另一个内核。因此,例如,使用此Windows代码:
void Processor::ConnectionThread()
{
while (work)
{
Iterate();
}
}在任务管理器中,我没有看到"100%被占用“核心,总体系统负载是36.40%。
但如果我把它改为:
void Processor::ConnectionThread()
{
SetThreadAffinityMask(GetCurrentThread(), 2);
while (work)
{
Iterate();
}
}然后我看到其中一个CPU内核被100%占用,整个系统负载也减少到34-36%。
这是否意味着我应该倾向于使用SetThreadAffinityMask来“旋转”线程?如果我改进了延迟添加SetThreadAffinityMask在这种情况下?对于“自旋”线程,我还应该做什么来改善延迟呢?
我正在将我的应用程序移植到Linux中,所以这个问题更多的是关于Linux (如果这一点重要的话)。
upd发现了这张幻灯片,它表明将繁忙等待线程绑定到CPU可能有帮助:

发布于 2014-09-23 15:59:59
如果在代码中这是最重要的事情,那么在大多数情况下,运行锁定到单个核心的线程会为该线程提供最佳延迟。
理由(R)是
除非
因此,如果您需要少于100 on的延迟,以防止您的应用程序爆炸,您需要防止或减少SMT的影响,中断和任务切换到您的核心。最好的解决方案是一个http://en.wikipedia.org/wiki/RTLinux。这是一个几乎完美的匹配您的目标,但这是一个新的世界,如果你大部分已经完成了服务器和桌面编程。
将线程锁定到单个核心的缺点是:
使用在SU中运行的具有赛特赛德帕拉姆和最高优先级的SCHED_FIFO,并将其锁定到内核和其邪恶的孪生节点上,可以保护所有这些延迟的最佳延迟,只有实时操作系统才能消除所有上下文切换。
其他链接:
关于中断的讨论
您的Linux可能会接受调用集调度器,使用SCHED_FIFO,但这要求您拥有自己的PID,而不仅仅是一个TID,或者您的线程是协作的多任务处理。
这可能并不理想,因为您的所有线程都是“自愿的”开关,从而消除了内核调度它的灵活性。
100中的进程间通信
发布于 2014-09-21 19:20:00
将任务固定在特定处理器上通常会为任务提供更好的性能。但是,在这样做的时候,有很多细微差别和成本需要考虑。
强制执行关联时,会限制操作系统的调度选择。增加剩余任务的cpu争用。因此,包括操作系统本身在内的系统上的所有其他都会受到影响。您还需要考虑的是,如果任务需要跨内存通信,并且将关联设置为不共享缓存的cpus,则可以大大增加跨任务通信的延迟。
但是,设置任务cpu亲和力的最大原因之一是它提供了更可预测的缓存和tlb ()行为。当任务切换cpu时,操作系统可以将其切换到无法访问上一个cpu的缓存或tlb的cpu。这会增加任务的缓存丢失。这尤其是一个跨任务交流的问题,因为跨越更高级别的缓存和最坏的内存需要更多的时间。要在linux上测量缓存统计信息(一般性能),我建议使用perf。
最好的建议是,在你试图修复亲缘关系之前,先衡量一下。量化延迟的一个好方法是使用rdtsc指令(至少在x86上)。这将读取cpu的时间源,这通常会提供最高的精度。跨事件的测量将提供大约纳秒的精度。
volatile uint64_t rdtsc() {
register uint32_t eax, edx;
asm volatile (".byte 0x0f, 0x31" : "=d"(edx), "=a"(eax) : : );
return ((uint64_t) edx << 32) | (uint64_t) eax;
}rdtsc指令需要与负载栅栏相结合,以确保所有以前的指令都已完成(或使用rdtscp)。rdtsc时没有固定的时间源(在linux grep constant_tsc /proc/cpuinfo上,则在频率变化和任务切换cpu (时间源)时可能得到不可靠的值。因此,一般来说,是的,设置亲和力确实会降低延迟,但这并不总是正确的,而且当您这样做时会付出非常严重的代价。
一些额外的阅读..。
发布于 2016-06-15 21:45:01
我遇到这个问题是因为我处理的是同一个设计问题。我正在建造一套HFT系统,每毫秒计一纳秒。在阅读了所有答案之后,我决定实现4种不同的方法并对其进行基准测试。
不可动摇的胜利者是“忙碌的等待与亲和力的集合”。这一点毫无疑问。
现在,正如许多人所指出的,为了允许操作系统自由运行,一定要让两个内核免费运行。
在这一点上,我唯一关心的是,对于那些100%运行数小时的内核是否有一些物理伤害。
https://stackoverflow.com/questions/25933912
复制相似问题