我正在编写一些产生相当多线程的代码(目前约为512个,但未来可能会更高)。每个线程只执行少量操作,因此我希望线程在系统上的开销保持在最低限度。
我使用pthread_attr_setstacksize()
设置堆栈大小,我可以从PTHREAD_STACK_MIN
获得允许的最小堆栈大小。但我的问题是:将PTHREAD_STACK_MIN
用于线程堆栈大小是否安全?如何计算我需要多少堆栈?是否有任何隐藏的开销需要添加到我的计算中?
此外,还有其他技术可以用来减少线程在系统上的负担吗?
答案 0 :(得分:7)
你不应该在那么多线程附近创建任何东西,你绝对不应该创建一个新线程来执行少量操作。当且仅当您的现有线程完全饱和并且有更多可用的物理或逻辑关注才能工作时,您应该创建一个新线程。这对大约10个线程左右的合理当前应用程序施加了硬性限制,即使你在hexacore上运行,你最多只需要12个左右。这样的设计存在很大缺陷,会占用大量的进程内存,并且不会真正提高性能。
至于堆栈大小,你无法真正计算出任意线程需要多少,因为它完全取决于代码运行。但是,在Visual Studio中,典型的堆栈大小是几兆字节。您必须发布整个代码以及线程执行的反汇编,以了解要使用的堆栈大小。只需坚持几兆字节即可。
答案 1 :(得分:5)
所需的堆栈帧大小取决于您使用的编译器,基本上您可以尝试猜测自动变量的大小,参数和返回地址的一些开销,保存寄存器等。
您应该考虑是否可以使用Thread Pool。由于线程的创建不是免费的。
答案 2 :(得分:4)
减少线程堆栈大小不会减少开销(不会降低CPU,内存使用或性能)。在这方面,您唯一的限制是为平台上的线程提供的总可用虚拟地址空间。
我会使用默认的堆栈大小,直到平台出现问题(如果它发生的话)。如果出现问题,请尽量减少堆栈使用。然而,这些将导致真正的性能问题,因为您需要在堆中,或devise thread-dependent allocation其他地方。
隐藏的管理费用可能包括:
alloca()
或只是简单的静态大小的自动数组。boost::bind
,可变参数模板,疯狂的宏,然后使用缓冲区或堆栈上的大对象进行一般递归。您还可以设置堆栈大小,操作线程优先级,并根据需要暂停和恢复它们,这将显着地帮助调度程序和系统响应。 Pthreads允许您设置争用范围; LWP并且范围调度的性能特征差异很大。
以下是一些有用的链接: