【问题标题】:How can I implement an algorithm for multicore in Java?如何在 Java 中实现多核算法?
【发布时间】:2009-03-14 20:47:37
【问题描述】:

现代计算机的内核越来越多。我们想改变我们当前的线性算法来使用这些内核。

只有在有空闲处理器的情况下,拆分任何算法以使用不同的线程才有意义。

如果有空闲处理器,是否有任何好的库可以帮助并行化某些步骤?

我会举一些例子。

  • 如果只有一个处理器,创建多个线程是没有意义的。它会降低速度。
  • 如果在一个 core duo 上运行 2 个进程(服务器上的请求),那么启动线程也是没有意义的。
  • 如果一个核心二重奏上只有一个进程,那是有意义的。

抽象算法有 4 个步骤 A、B、C 和 D。步骤 A、B 和 C 可以并行执行。步骤 D 需要 A、B 和 C 的结果。

编辑:我的意思是数学算法。无 IO,无事件等

【问题讨论】:

  • 即使添加了编辑,仍有很多原因导致您的线程被暂停。所以我还是觉得你的例子不是很好。

标签: java algorithm multithreading multicore


【解决方案1】:

这不一定是真的。

根据算法,将其拆分为多个线程通常是有意义的,即使只有一个内核可用。如果套接字、IO 等有任何等待,您可以从中受益。如果有 2 个进程,则“其他”进程可能不会 100% 使用其他核心,因此线程在这里可以提供帮助。在这种情况下,请相信您的操作系统能够正确处理它。

您始终可以使用 Runtime.availableProcessors() 检查处理器计数,以确定如何将其拆分为单独的线程。或者,您可以使用线程池,它应该可以随着更多处理器正确扩展。

不过,一般来说,如果算法对并行化有意义,我会设计您的算法以使用多个处理器。大多数系统将有更多可用的内核/处理器,如果你发现它需要它,你可以随时调整你的实现。如果进程运行时间很长,那么生成线程的开销是值得的——如果它已经很快了,可能更值得寻找其他地方进行优化。

【讨论】:

    【解决方案2】:

    查看 Java 5 及更高版本中的各种并发类。你很可能想要一个 ThreadPoolExecutor - http://java.sun.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html

    线程池的适当值很可能因系统而异,具体取决于工作负载和硬件架构。使其用户可调整。

    【讨论】:

      【解决方案3】:

      有关一些想法,请查看JSR166 and JSR166y(类似于具有工作窃取 (166) 和并行数组 (166y) 的分叉连接系统)。

      一些不错的阅读和对 Java 未来方向的概述。看起来还不错(对高级并发和并行编程的强大支持)。

      【讨论】:

        【解决方案4】:

        我经常有一个固定的线程池,它的线程数与处理器的数量动态相同(请参阅运行时) 我将任务添加到此线程池,以便它使用所有可用的处理器。

        我认为您不应该尝试在操作系统中重新发明进程调度程序。它做得很好,所以让它做它做得好的事情。

        【讨论】:

          【解决方案5】:

          拥有比核心更多的线程/进程不一定是坏事。如果您的代码是严格的数学代码,几乎没有 I/O 并且没有副作用,那么是的,内核和线程之间的 1:1 对应关系是最佳的。但通常情况并非如此。与时钟周期相比,I/O 需要数亿年。当操作系统可以交换另一个线程以继续运行时,为什么要在等待 I/O 时完全停止内核?

          问题是没有很多语言/编译器可以为您做出并发决定。您需要设计程序以利用并发性。而且您可能需要为多个目标环境设计程序,通常不受您的控制。因此,通常情况下,最佳实践是为任何有意义的事情创建线程以并行化并让线程调度程序处理它。应该调整线程调度程序以在特定硬件上使用,这比您针对“出现的任何硬件”调整程序要好得多。

          【讨论】:

            【解决方案6】:

            抽象算法有4个步骤A, B、C 和 D。步骤 A、B 和 C 可以 并行执行。步骤 D 需要 A、B 和 C 的结果。

            这是一个使用 Ateji PX 表示法的单行代码,Java 语言的扩展:

            [ A(); || B(); || C(); ]; D();
            

            作为程序员,你的职责是表达哪里有可能并行执行,这就是双杠“||”的作用在代码中。调度程序现在能够充分利用可用硬件,即在可用时在三个不同的内核上运行 A、B 和 C。

            这是一个非常高级的视图,可能会在 A、B 或 C 内部展示更多的并行性。

            【讨论】:

              【解决方案7】:

              我认为您需要来自 Javolution 的 ConcurrentContext。见http://javolution.org/target/site/apidocs/javolution/context/ConcurrentContext.html

              【讨论】:

                猜你喜欢
                • 2011-05-13
                • 1970-01-01
                • 1970-01-01
                • 2019-04-02
                • 2011-02-12
                • 1970-01-01
                • 2011-08-11
                • 1970-01-01
                • 2012-10-22
                相关资源
                最近更新 更多