简体   繁体   English

如何在Java中实现多核算法?

[英]How can I implement an algorithm for multicore in Java?

Modern computers have more and more cores. 现代计算机具有越来越多的内核。 We want to change our current linear algorithm to use these cores. 我们想要更改当前的线性算法以使用这些核。

A splitting of any algorithm to use different threads only makes sense if there is a free processor. 仅当有空闲处理器时,将任何算法拆分为使用不同的线程才有意义。

Are there any good libraries that can help to parallelize some steps if there are free processors? 如果有免费的处理器,是否有任何好的库可以帮助并行化某些步骤?

I will give some examples. 我会举一些例子。

  • If there is only one processor it makes no sense to create multiple threads. 如果只有一个处理器,则创建多个线程是没有意义的。 It will reduce the speed. 它将降低速度。
  • If there run 2 processes (requests on a server) on a core duo it make also no sense to start threads. 如果在核心二人组上运行2个进程(服务器上的请求),则启动线程也没有意义。
  • If there only one process on a core duo it make sense. 如果一个核心二人组上只有一个进程,那是有道理的。

The abstract algorithm has 4 steps A, B, C and D. Steps A, B and C can execute parallel. 抽象算法具有4个步骤A,B,C和D。步骤A,B和C可以并行执行。 Step D needs the results from A, B and C. 步骤D需要A,B和C的结果。

Edit: I means an mathematic algorithm. 编辑:我的意思是一种数学算法。 No IO, No events, etc 没有IO,没有事件等

This isn't necessarily true. 这不一定是真的。

Depending on the algorithm, it often makes sense to split it into multiple threads even if there is only a single core available. 根据算法的不同,即使只有一个内核可用,将其拆分为多个线程也很有意义。 If there is any waiting on sockets, IO, etc, you can get benefits from this. 如果套接字,IO等上有任何等待,您可以从中受益。 If there are 2 processes, the "other" process may not be using 100% of the other core, so threading can help here. 如果有2个进程,则“其他”进程可能未使用100%的其他内核,因此线程在这里可以提供帮助。 Trust your OS in this case to handle it correctly. 在这种情况下,请信任您的操作系统以正确处理它。

You can always check the processor count with Runtime.availableProcessors() to determine how to split it into separate threads. 您始终可以使用Runtime.availableProcessors()检查处理器数量,以确定如何将其拆分为单独的线程。 Alternatively, you can use a threadpool, which should scale correctly with more processors. 或者,您可以使用线程池,该线程池应在更多处理器上正确扩展。

In general, though, I would design your algorithm to use more than one processor if the algorithm makes sense to parallelize. 不过,总的来说,如果可以并行化,我会设计您的算法使用多个处理器。 Most systems will have more cores/processors available, and you can always tweak your implementation later if you find it needs it. 大多数系统将具有更多可用的内核/处理器,如果以后发现需要,可以随时对实现进行调整。 If the process is long running, the overhead of generating the thread will be worth it - if it's already fast, it may be more worthwhile looking at other places to optimize. 如果该进程运行时间长,那么生成线程的开销将是值得的;如果它已经很快,那么寻找其他地方进行优化可能更值得。

Look at the various concurrent classes in Java 5 and onwards. 查看Java 5及更高版本中的各种并发类。 You most likely want a ThreadPoolExecutor - http://java.sun.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html . 您最可能希望使用ThreadPoolExecutor- http://java.sun.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html

The appropriate value of the ThreadPool will most likely vary from system to system depending on work load and hardware architechture. ThreadPool的适当值很可能会因工作负载和硬件体系结构而异,因系统而异。 Make it user adjustable. 使其用户可调。

The abstract algorithm has 4 steps A, B, C and D. Steps A, B and C can execute parallel. 抽象算法具有4个步骤A,B,C和D。步骤A,B和C可以并行执行。 Step D needs the results from A, B and C. 步骤D需要A,B和C的结果。

This is a one-liner using the Ateji PX notation, an extension of the Java language: 这是使用Ateji PX表示法(Java语言的扩展)的单行代码:

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

Your responsability as a programmer is to express where there is a potential for parallel execution, that's the role of the parallel bars "||" 您作为程序员的责任是表达在哪里有可能执行并行,这就是平行杠“ ||”的作用。 in the code. 在代码中。 The scheduler now is able to make the best use of available hardware, namely run A, B and C on three different cores whenever available. 现在,调度程序可以充分利用可用的硬件,即在可用时在三个不同的内核上运行A,B和C。

This is a very high-level view, more parallelism may possibly be exhibited inside A, B or C. 这是一个非常高级的视图,可能在A,B或C内部表现出更多的并行性。

For some ideas have a look at JSR166 and JSR166y (something like fork-join system with work stealing (166) and parallel array (166y) ). 对于某些想法,请看一下JSR166和JSR166y (类似于带有工作窃取功能(166)和并行阵列(166y)的fork-join系统)。

Some nice reading and overview of the future directions for Java. 对Java的未来方向有一些不错的阅读和概述。 Looks not that bad (strong support for high level concurrent and parallel programming). 看起来还不错(强烈支持高级并发和并行编程)。

I often have a fixed thread pool which is dynamically the same number of thread as the number of processors (see Runtime) I add tasks to this thread pool so it uses all the processors available. 我经常有一个固定的线程池,该线程池的线程数与处理器的数量动态相同(请参阅运行时),我向该线程池添加任务,以便它使用所有可用的处理器。

I don't believe you should try re-inventing the process scheduler in the operating system. 我不认为您应该尝试在操作系统中重新发明流程调度程序。 It does a good job so let it do what it does well. 它做得很好,所以就让它做好它。

Having more threads/processes than cores is not necessarily a bad thing. 具有比核心更多的线程/进程不一定是一件坏事。 If your code is strictly mathematical with little I/O and no side effects, then yes, having a 1:1 correspondence between cores and threads is optimal. 如果您的代码严格来说是数学的,且I / O很少且没有副作用,那么可以,内核与线程之间的1:1对应关系是最佳选择。 But this is not usually the case. 但这通常不是这种情况。 I/O takes eons compared to clock cycles. 与时钟周期相比,I / O花费了无数的时间。 Why stall the core completely while waiting on I/O when the OS can swap in another thread to keep chugging along? 当操作系统可以交换另一个线程以保持同步时,为什么在等待I / O时完全停滞内核呢?

The problem is there aren't a lot of languages/compilers that will make the concurrency decision for you. 问题在于,没有多少语言/编译器会为您做出并发决策。 You need to design your program to take advantage of concurrency. 您需要设计程序以利用并发性。 And you probably need to design your program for multiple target environment, usually not under your control. 您可能需要针对多个目标环境设计程序,通常情况下不受您的控制。 So usually, best practice is to make threads for things whatever it makes sense to parallelize and let the thread scheduler handle it. 因此,通常,最佳实践是使线程并行处理,并由线程调度程序处理。 The thread scheduler should be tuned for use on the specific hardware in question far better than you can tune your program for "whatever hardware comes along". 应该调整线程调度程序以在有问题的特定硬件上使用,比为“随随便便的硬件”调整程序要好得多。

I think you need a ConcurrentContext from Javolution. 我认为您需要来自Javolution的ConcurrentContext。 See at http://javolution.org/target/site/apidocs/javolution/context/ConcurrentContext.html 参见http://javolution.org/target/site/apidocs/javolution/context/ConcurrentContext.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM