C 在什么情况下,添加更多线程会停止帮助?

C 在什么情况下,添加更多线程会停止帮助?,c,pthreads,C,Pthreads,我有一台4核的计算机,我有一个程序,可以创建一个N x M的网格,从1 x 1的正方形到一个巨大的网格。然后,该程序用数字填充,并对每个数字进行计算,将所有数字相加求平均值,直到它们达到大致相同的数字。这样做的目的是创建大量繁忙的工作,因此必须使用并行线程进行计算 如果我们有一个可选参数来选择使用的线程数,那么哪个线程数最适合优化繁忙的工作以使其尽快运行 使用4个线程是否比使用1个线程快4倍?15条线怎么样?50? 在某种程度上,我觉得我们会受到计算机硬件(内核数量)的限制,添加更多线程将不再有

我有一台4核的计算机,我有一个程序,可以创建一个N x M的网格,从1 x 1的正方形到一个巨大的网格。然后,该程序用数字填充,并对每个数字进行计算,将所有数字相加求平均值,直到它们达到大致相同的数字。这样做的目的是创建大量繁忙的工作,因此必须使用并行线程进行计算


如果我们有一个可选参数来选择使用的线程数,那么哪个线程数最适合优化繁忙的工作以使其尽快运行


使用4个线程是否比使用1个线程快4倍?15条线怎么样?50? 在某种程度上,我觉得我们会受到计算机硬件(内核数量)的限制,添加更多线程将不再有帮助(甚至可能会阻碍?

我认为最好的回答是首先概述一下系统如何管理线程。现在所有的处理器实际上都是多核的,每个核都有多线程,但是为了简单起见,让我们先想象一个单核处理器和单线程。这在物理上是有限的,只能执行一个单一的任务,但我们仍然能够运行多任务程序

那么这怎么可能呢?这只是一种错觉

CPU当时仍在执行单个任务,但会在一个任务和另一个任务之间切换,给人多任务的错觉。从一个任务更改为另一个任务的过程称为

在上下文切换期间,将保存与正在运行的任务相关的所有数据,并加载与下一个任务相关的数据。取决于CPU的体系结构,数据可以保存在寄存器、缓存、RAM等中。技术越先进,发现的解决方案就越多。当任务恢复时,将获取整个数据,任务将继续其操作

此概念在管理任务时引入了许多问题,例如:

  • 同步
  • 还有其他几点,但这只是一个简单的列表,因为问题并不集中于此

    回到你的问题:


    如果我们有一个可选参数来选择使用的线程数,那么哪个线程数最适合优化繁忙的工作以使其尽快运行

    使用4个线程是否比使用1个线程快4倍?15条线怎么样?50? 在某种程度上,我觉得我们会受到计算机硬件(内核数量)的限制,增加更多线程将不再有帮助(甚至可能会阻碍?)

    简短回答:视情况而定

    如前所述,要在任务和另一个任务之间切换,需要上下文切换。要执行此操作,需要一些存储和获取数据的操作,但这些操作只是计算的开销,不会直接给您带来任何好处。因此,有太多的任务需要大量的上下文切换,这意味着浪费了大量的计算时间!因此,到最后,您的任务可能会比任务较少时运行得慢

    另外,由于您使用pthreads标记了这个问题,因此还需要检查代码是否编译为在多个硬件内核上运行。拥有多核CPU并不保证多任务代码将在多个硬件内核上运行

    在您的特殊应用情况下:

    我有一台4核的计算机,我有一个程序,可以创建一个N x M的网格,从1 x 1的正方形到一个巨大的网格。然后,该程序用数字填充,并对每个数字进行计算,将所有数字相加求平均值,直到它们达到大致相同的数字。这样做的目的是创建大量繁忙的工作,因此必须使用并行线程进行计算


    是并发和数据独立计算的一个很好的例子。这类任务在GPU上运行得很好,因为操作没有数据关联,并行计算是在硬件上执行的(现代GPU有数千个计算核心!)

    通常,即使在多核系统上,性能也不会随着线程数的增加而线性扩展。特别是当您需要在线程之间进行某种同步时。如果系统的线程总数大于核心数(通常情况下,除非您在某种专用系统上),那么所有线程都必须“争夺”您拥有的核心。你迟早会到达一个临界点,系统在线程之间切换的时间比实际运行线程的时间要多。因为大多数时候答案是“这取决于”一般来说,如果您添加了更多线程,您不会获得更多的功能,除非您还可以使用另一个内核,或者您的线程被I/O阻塞。这意味着超过4个线程可能不会为纯数字运算带来任何性能好处。此外,您的问题要求线程的紧密同步。您可以执行一次平均,然后需要处理每个线程修改的区域边界。这也限制了性能gain@Someprogrammerdude当通过系统调用或硬件中断/驱动程序输入时,系统只能更改运行线程集。在OP的CPU密集型示例中,似乎没有系统调用,也没有I/O完成,只留下页面错误和周期性计时器中断作为可以运行重新调度的点。计时器间隔通常是固定的,与就绪线程的数量无关:不管是4个还是4000个实时线程,重新调度仍然只会每隔10毫秒或其他时间发生一次。那么,什么是“临界点”?页面错误?“如果我们有一个可选参数来选择使用的线程数”,那么您可以简单地测试它,不是吗?测试结果比事先猜测要令人满意得多:)太棒了。谢谢你的回答!