Java或C#(或旧的C)?
目前,我正在决定建立一个科学计算产品的平台,并决定使用Core2 Quad CPU上的Intel编译器的C#,Java或普通C语言。 它主要是整数算术。
到目前为止,我的基准测试显示Java和C大致相同,而.NET / C#则落后了大约5% - 然而,我的许多同事都声称,如果.NET具有正确的优化,足够的时间将会胜过这两者让JIT去做它的工作。
我总是认为JIT会在应用程序启动后几分钟内完成它的工作(可能在我的情况下几秒钟,因为它大多是紧密的循环),所以我不确定是否相信它们
任何人都可以阐明这种情况吗? .NET会击败Java吗? (或者我最好在这点上坚持C?)。
代码是高度多线程的,数据集的大小是几个兆字节。
在这种情况下,Haskell / Erlang等不是选项,因为有大量现有的传统C代码将移植到新系统中,并且将C移植到Java / C#比Haskell或Erlang简单得多。 (除非这些提供了显着的加速)。
编辑:我们正在考虑转向C#或Java,因为它们理论上可能会更快。 我们可以削减处理时间的每一个百分比为我们每年节省数万美元。 在这一点上,我们只是试图评估C,Java或c#是否会更快。
问题中的关键信息是:
我们可以削减处理时间的每一个百分比为我们每年节省数万美元
因此,您需要考虑削减每个百分点的成本费用。 如果这种优化工作每年花费数万美元,那么这是不值得的。 你可以通过解雇一名程序员来节省更多的钱。
有了正确的技能(今天更加罕见,因此成本更高),您可以手工编制汇编器以获得尽可能快的代码。 由于少一些稀有(而且昂贵)的技能,你可以做一些非常丑陋的C代码。 等等。 您挤出的表现越多,您在开发过程中所付出的代价就越大,并且会有越来越大的努力收益递减。 如果从中获得的利润保持“每年数万美元”,那么就会有一个不值得付出的努力。 事实上,我估计你已经在那个时候了,因为“每年几万美元”在一个薪水范围内,可能还不足以购买手工优化复杂项目所需的技能。
我猜想如果你的代码已经用C语言编写,那么将其全部重写为另一种语言的直接翻译将会浪费90%的工作量。 它很可能会慢一些,因为你不会利用平台的功能,而是对付它们,例如试图像使用Java一样使用Java。
同样在你现有的代码中,会有一些对运行时间(它们频繁运行)作出重要贡献的部分,以及其他完全不相关的部分(它们很少运行)。 所以如果你对加速程序有一些想法,浪费时间将它应用到程序中不影响运行时间的部分是没有经济意义的。
因此,使用探查器来查找热点,并查看现有代码中浪费的时间。
当我注意到代码的引用是“多线程”时更新
在这种情况下,如果您专注于消除瓶颈,以便您的程序可以很好地扩展到大量内核,那么它每年的速度会自动加快,从而使您可以进行的任何其他优化变得更加黯淡。 明年这一次,四核将成为台式机的标配。 在那之后的一年里,8核心将会越来越便宜(我在一年前买了一个数千美元),并且我预测到那时32核心机器的开发成本将低于开发人员。
我很抱歉,但这不是一个简单的问题。 这将取决于究竟发生了什么。 C#肯定没有懒散,你会很难说“java更快”或“C#更快”。 C是一个非常不同的野兽......它可能有更快的速度 - 如果你做得对; 但在大多数情况下,它大致相同,但写得更难。
这也取决于你如何做 - 锁定策略,如何进行并行化,主代码体等。
Re JIT - 你可以用NGEN来压扁这个,但是是的; 如果你打的是相同的代码,它应该很早就打开。
C#/ Java(over C)的一个非常有用的特性是它们有可能更好地利用本地CPU(优化等),而不必担心它。
另外 - 对于.NET,考虑诸如“并行扩展”(捆绑在4.0中),这会给你一个更强大的线程故事(与没有PFX的.NET相比)。
不要担心语言; 并行!
如果你有一个高度多线程,数据密集型的科学代码,那么我认为不担心语言对你来说是最大的问题。 我认为你应该专注于使你的应用程序并行,尤其是使它扩展到单个节点。 这将使您获得比仅仅切换语言更多的性能。
只要您仅限于单个节点,您的应用程序的计算能力和带宽就会很低。 在即将推出的多核心机器上,目前尚不清楚您是否拥有在所有内核上进行数据密集型计算所需的带宽。 您可以执行计算密集型工作(如GPU),但如果需要将大量数据传输到每个核心,则可能无法提供所有核心。
我认为你应该考虑两个选择:
MapReduce的
您的问题听起来像Hadoop,这是专为非常数据密集型工作而设计的。
Hadoop在Linux上已经扩展到10,000个节点,并且可以将你的工作分流给其他人(例如亚马逊,微软)或你自己的计算云。 它是用Java编写的,因此就移植而言,您可以从Java中调用现有的C代码,也可以将整个代码移植到Java中。
MPI
如果您不想麻烦移植到MapReduce,或者由于某种原因您的并行范例不适合MapReduce模型,则可以考虑将您的应用程序改为使用MPI。 这也可以让你扩展到(可能有数千个)内核。 MPI是计算密集型分布式内存应用程序的事实标准,我相信有Java绑定,但大多数人使用MPI与C,C ++和Fortran。 因此,您可以将代码保留在C中,并专注于对性能密集型部件进行并行化。 如果您有兴趣,请查看OpenMPI的初学者。