安全线程堆栈大小?

Lee*_*ton 5 c pthreads stack-size

我正在编写一些产生相当多线程的代码(目前约为512,但未来可能会更高).每个线程只执行少量操作,因此我希望线程在系统上的开销保持在最低限度.

我正在设置堆栈大小pthread_attr_setstacksize(),我可以从中获得最小的允许堆栈大小PTHREAD_STACK_MIN.但我的问题是:使用PTHREAD_STACK_MIN线程堆栈大小是否安全?我如何计算我需要多少堆栈?是否有任何隐藏的开销需要添加到我的计算中?

此外,还有其他技术可以用来减少线程在系统上的负担吗?

Pup*_*ppy 7

你不应该在那么多线程附近创建任何东西,你绝对不应该创建一个新线程来执行少量操作.当且仅当您的现有线程完全饱和并且有更多可用的物理或逻辑关注才能工作时,您应该创建一个新线程.这对大约10个线程左右的合理当前应用程序施加了硬性限制,即使你在hexacore上运行,你最多只需要12个左右.这样的设计是非常有缺陷的,会使用大量的进程内存,并不会真正提高性能.

至于堆栈大小,你无法真正计算出任意线程需要多少,因为它完全取决于代码运行.但是,在Visual Studio中,典型的堆栈大小是几兆字节.您必须发布整个代码以及线程执行的反汇编,以了解要使用的堆栈大小.只需坚持几兆字节即可.

  • @C.罗斯:取决于他/她是如何约束的.好的,所以还有其他方法可以构建一个资源效率更高的异步I/O系统(可能在我的时间效率较低,这取决于我对事件队列的好处,`select`等),但是如果我的线程他们将花99.8%的时间等待网络I/O,然后我会想要500个线程.有时RAM比程序员便宜,有时它不是;-) (4认同)

sta*_*ker 5

所需的堆栈帧大小取决于您使用的编译器,基本上您可以尝试猜测自动变量的大小,参数和返回地址的一些开销,保存寄存器等.

您应该考虑它是否可以替代使用线程池.由于线程的创建不是免费的.


Mat*_*ner 4

减少线程堆栈大小不会减少开销(不是在 CPU、内存使用或性能方面)。在这方面,您的唯一限制是为平台上的线程提供的总可用虚拟地址空间。

我会使用默认的堆栈大小,直到平台出现问题(如果确实发生)。如果出现问题,则尽量减少堆栈的使用。然而,这些将导致真正的性能问题,因为您需要使用堆,或者在其他地方设计依赖于线程的分配

隐藏的管理费用可能包括:

  • 在堆栈上分配大型数组,例如通过VLA 分配alloca()或者只是简单的静态大小的自动数组。
  • 您无法控制或不知道使用模板、工厂类等的后果的代码。但是,鉴于您没有指定 C++,这不太可能成为问题。
  • 从库头等导入的代码。这些可能会在版本之间发生变化,并显着改变它们的堆栈,甚至线程使用。
  • 递归。发生这种情况也是由于上述几点,考虑诸如boost::bind可变参数模板、疯狂宏之类的东西,然后只是使用缓冲区或堆栈上的大对象的一般递归。

除了设置堆栈大小之外,您还可以操作线程优先级,并根据需要暂停和恢复它们,这将极大地帮助调度程序和系统响应能力。Pthreads 允许您设置争用范围;LWP和范围内调度的性能特征差异很大。

以下是一些有用的链接:

  • @ltn100:不,它更像是“在调试上下文中使用指定的堆栈大小彻底测试代码,这将检测溢出。然后添加 10% 以获得好运”。 (2认同)
  • @ltn100:如果你能找到一个调试工具来实际测量你的平台上的高水位线堆栈使用情况,那很好,但是你实际需要执行此操作的平台(因为堆栈是前面的物理 RAM)不一定是拥有最好的调试工具的人。而且你必须“真正”彻底地进行测试。任何小事情,包括对动态链接库的更改,或者它们查看的环境变量,或者(字面意思)一周中的某一天,都可能会增加您的高水位线。避免 VLA,避免任何依赖于输入数据的递归。 (2认同)