我刚开始在双核x86_64 Linux系统上使用POSIX线程进行编程。似乎有256个线程以我完成它的方式表现出最佳性能。我想知道这是怎么回事?如果它可能意味着我的方法是错误的并且更好的方法需要更少的线程并且速度更快或更快?
有关更多背景信息(有问题的程序是多线程M-set图像生成器的框架),请参阅我已经提出的以下问题:
Using threads, how should I deal with something which ideally should happen in sequential order?
How can my threaded image generating app get it’s data to the gui?
也许我应该提到骨架(我在其中再现了用于测试和比较的最小功能)现在正在显示图像,并且实际计算的速度几乎是非线程程序的两倍。
因此,如果运行速度超过8个线程的256个线程并不表示线程处理方式不佳,那么256个线程的表现如何优于8个线程呢?
速度测试用例是Mandelbrot Set的一部分位于:
xmin -0.76243636067708333333333328
xmax -0.7624335575810185185185186
ymax 0.077996663411458333333333929
计算最多30000次迭代。
在我的系统上non-threaded version渲染时间约为15秒。在线程版本中,8个线程的平均速度为7.8秒,而256个线程的平均速度为7.6秒。
答案 0 :(得分:4)
嗯,可能是的,你做错了什么。
但是,在某些情况下,256个线程的运行性能优于8个,而不必使用错误的线程模型。必须记住,拥有8个线程并不意味着所有8个线程实际上一直在运行。每当一个线程向操作系统发出阻塞系统调用时,该线程将停止运行并等待结果。与此同时,另一个线程通常可以正常工作。
有一个神话,一个人无法在CPU上使用比上下文更多的线程,但事实并非如此。如果您的线程阻塞了系统调用,那么让另一个线程可用于执行更多工作至关重要。 (实际上,当线程阻塞时,往往需要做的工作较少,但情况并非总是这样。)
这一切都非常依赖于工作负载,并且任何特定应用程序都没有合适的线程数。通常,您永远不会想要比运行操作系统更少的线程可用,这是唯一真正的规则。 (不幸的是,这可能很难找到,因此人们倾向于启动与上下文一样多的线程,然后尽可能使用非阻塞系统调用。)
答案 1 :(得分:2)
可能是你的应用程序被绑定了吗?如何生成图像数据?
答案 2 :(得分:1)
通过分配比核心更多的线程而获得的性能提升表明CPU不是瓶颈。如果涉及I / O访问,例如磁盘,内存甚至网络访问,那么您的结果就非常有意义。
答案 3 :(得分:1)
您可能会受益于Simultaneous Multithreading (SMT)。您的操作系统会调度比可用内核更多的线程,并且会交换进出未等待资源的线程(例如内存负载)。这可以非常有效地隐藏内存系统与程序的延迟,并且这种技术对于CUDA中用于通用GPU编程的大规模并行化具有很好的效果。
答案 4 :(得分:1)
如果你看到通过跳转到256个线程的性能提升,那么你可能正在处理的是资源瓶颈。在某些时候,您的代码正在等待一些慢速设备(例如硬盘或网络连接)才能继续。使用多个线程,等待这个慢速设备不是问题,因为CPU可以在第一个线程在慢速设备上等待的同时处理另一个线程,而不是闲置和摆弄它的电子拇指。正在运行的并行线程越多,CPU在等待其他东西时就可以做的工作就越多。
如果你看到性能一直提升到256个线程,我很想说你在某个地方有一个主要的性能瓶颈而且它不是CPU。要测试这一点,请尝试查看是否可以测量单个线程的空闲时间。我怀疑你会看到你的线程在其生命的较长时间内处于“阻塞”或“等待”状态,而不是在“运行”或“活动”状态下。一些调试器或函数分析工具可以让你这样做,我认为还有Linux工具可以在命令行上执行此操作。