代码之家  ›  专栏  ›  技术社区  ›  James Morris

如果256个线程的性能比8好,我是否可能得到了错误的方法?

  •  2
  • James Morris  · 技术社区  · 15 年前

    我刚开始在双核x86 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?

    也许我应该提到骨架(我在其中复制了用于测试和比较的最小功能)现在正在显示图像,实际计算的速度几乎是非线程程序的两倍。

    因此,如果256个线程的运行速度超过8个线程,并不意味着线程处理方法不好,那么为什么256个线程的性能比8个线程好呢?

    速度测试用例是 Mandelbrot Set 位于:

    xmin -0.76243636067708333333333328
    xmax -0.7624335575810185185185186
    ymax 0.077996663411458333333333929
    

    最多可计算30000次迭代。

    non-threaded version 我的系统渲染时间大约是15秒。在线程版本中,8个线程的平均速度为7.8秒,而256个线程的平均速度为7.6秒。

    5 回复  |  直到 15 年前
        1
  •  4
  •   DJ Capelis    15 年前

    嗯,可能是的,你做错了什么。

    但是,在某些情况下,256个线程比8个线程运行得更好,而不必使用坏的线程模型。必须记住,拥有8个线程并不意味着所有8个线程实际上一直在运行。每当一个线程对操作系统进行阻塞系统调用时,该线程将停止运行并等待结果。同时,另一个线程经常可以工作。

    有这样一个神话,即一个人不能有效地使用比CPU上的上下文更多的线程,但事实并非如此。如果您的线程在一个系统调用上阻塞,那么让另一个线程来做更多的工作可能很关键。(实际上,当线程阻塞时,要做的工作往往较少,但情况并非总是如此。)

    它完全依赖于工作负载,对于任何特定的应用程序都没有一个正确的线程数。通常情况下,您不希望使用比操作系统运行的线程少的线程,这是唯一正确的规则。(不幸的是,这可能很难发现,因此人们往往只启动尽可能多的线程作为上下文,然后尽可能使用非阻塞的系统调用。)

        2
  •  2
  •   Evert    15 年前

    你的应用程序是IO绑定的吗?如何生成图像数据?

        3
  •  1
  •   Spencer Ruport    15 年前

    通过分配比核心更多的线程而获得的性能改进表明CPU不是瓶颈。如果涉及到磁盘、内存甚至网络访问等I/O访问,那么您的结果将非常合理。

        4
  •  1
  •   Aron Ahmadia    15 年前

    你可能从中受益 Simultaneous Multithreading (SMT) . 您的操作系统调度的线程比可用的核心多,并且将交换未暂停的线程,以等待资源(如内存负载)。这可以非常有效地从程序中隐藏内存系统的延迟,并且是用于通用GPU编程的CUDA中大规模并行化的有效技术。

        5
  •  1
  •   bta    15 年前

    如果您看到性能随着跳转到256个线程而增加,那么您可能正在处理的是一个资源瓶颈。在某种程度上,您的代码正在等待一些较慢的设备(例如硬盘或网络连接)以继续。对于多个线程,等待这个慢设备不是问题,因为CPU可以在第一个线程等待慢设备时处理另一个线程,而不是坐在空闲状态,旋转电子拇指。运行的并行线程越多,CPU在等待其他东西时可以做的工作就越多。

    如果您看到性能一直提高到256个线程,我想说您在某个地方有一个主要的性能瓶颈,而不是CPU。要测试这一点,请尝试查看是否可以测量单个线程的空闲时间。我怀疑您会看到线程在其生命周期中停留在“阻塞”或“等待”状态的时间比在“运行”或“活动”状态下花费的时间要长。一些调试器或函数分析工具将允许您这样做,我认为在命令行上也有Linux工具可以这样做。