我正在研究一种科学应用,它可以很容易地分开并且可以并行进行.所以,我已经将这些部分作为独立线程写入每个运行,但不是因为看起来是将事物分成线程的标准原因(即,没有阻止某些退出命令等).
几个问题:
这实际上是否在标准的多核桌面上买了任何东西 - 也就是说,如果我有一个当前的JVM,那么线程实际上是在单独的内核上运行,还是我必须做其他事情?
我有很少的对象被所有线程读取(尽管从未写过).那个潜在的问题?这些问题的解决方案?
对于实际的集群,您是否可以推荐框架将线程分发到各个节点,这样我就不必自己管理(如果存在的话)?澄清:通过这种方式,我的意思是要么自动将线程转换为单个节点的任务,要么使整个集群看起来像一个JVM(即,它可以将线程发送到它可以访问的任何处理器)或其他什么.基本上,在集群上以有用的方式实现并行化,因为我已经将它构建到算法中,而我的工作量最小.
奖励:大多数评估包括集合比较(例如,union,intersection,contains)以及来自键的一些映射以获得相关集合.我在FORTRAN,C和C++(第一个科学计算学期和10年前的另外两个HS AP课程的学期)方面经验有限 - 如果我绑了我的话,我会发现什么样的速度/易于并行化收益? Java前端到其中一种语言的算法后端,以及我的经验水平可能会在那些语言中实现这些操作会带来什么样的麻烦?
是的,使用独立线程将在普通JVM中使用多个内核,而无需进行任何工作.
如果只读过任何东西,那么多线程读取它应该没问题.如果你可以使有问题的对象不可变(以保证它们永远不会被改变),那就更好了
我不确定你正在考虑什么样的集群,但你可能想看看Hadoop.请注意,分布式计算分配任务而不是线程(通常,无论如何).
Java运行时通常会调度线程以在所有可用的处理器和内核上并发运行.我认为可以限制这一点,但需要额外的工作; 默认情况下,没有限制.
对于只读对象,将其成员字段声明为final
,这将确保在创建对象时永远不会更改它们.如果字段不是final
,即使它在构造之后从未改变,在多线程程序中也可能存在一些"可见性"问题.这可能导致一个线程所做的分配永远不会对另一个线程可见.
应声明由多个线程访问的任何可变字段,volatile
通过同步保护,或使用其他一些并发机制来确保更改在线程之间保持一致和可见.
在Java中使用最广泛的分布式处理框架称为Hadoop.它使用了一种名为map-reduce的范例.
与其他语言集成不太可能值得.由于其自适应字节码到本机编译器,Java在各种计算任务上已经非常快.如果没有实际测试,假设另一种语言更快是错误的.此外,使用JNI与"本机"代码集成非常繁琐,容易出错且复杂; 使用像JNA这样的简单接口非常慢,很快就会消除任何性能提升.