高性能应用程序中的C / C ++与Java / C#

我的问题是关于Java与编译代码的性能,例如高性能数值应用程序中的C ++ / fortran / assembly。 我知道这是一个有争议的话题,但我正在寻找具体的答案/例子。 社区维基。 我以前曾问过类似的问题,但我认为我把它广泛地提出来并没有得到我想要的答案。

双精度矩阵矩阵乘法,通常称为blas库中的dgemm,能够实现接近100%的峰值CPU性能(就每秒浮动运算而言)。
有几个因素可以实现这种表现:

  • 缓存阻塞,实现最大内存局部性

  • 循环展开以最小化控制开销

  • 矢量指令,例如SSE

  • 内存预取

  • 保证没有内存别名

我已经看到很多使用汇编,C ++,fortran,Atlas,供应商BLAS的基准测试(典型情况是维度512及以上的矩阵)。 另一方面,我听说过Java等原理字节编译语言/实现可以快速或几乎与机器编译语言一样快。 但是我还没有看到明确的基准测试表明它是如此。 相反,似乎(根据我自己的研究)字节编译语言要慢得多。

你有没有很好的Java / C#矩阵矩阵乘法基准? 实时编译器(实际实现,而不是假设)能够产生满足我列出的点的指令吗?

谢谢

关于性能:每个CPU都具有峰值性能,具体取决于处理器每秒可执行的指令数量。 例如,现代2 ghz Intel CPU可以实现80亿双精度加/秒一秒,从而产生8 gflops的峰值性能。 矩阵矩阵乘法是能够在每秒操作次数方面实现几乎完全性能的算法之一,主要原因是计算内存操作的比率更高(N^3/N^2) 。 数字我对N > 500的订单感兴趣。

关于实现:阻塞等更高级别的细节是在源代码级别完成的。 较低级别的优化由编译器处理,可能还有关于对齐/别名的编译器提示。 字节编译的实现也可以使用块方法编写,因此原则上用于体面实现的源代码细节将非常相似。

VC ++ / .NET 3.5 / Mono 2.2在纯矩阵乘法场景中的比较:

http://img237.imageshack.us/img237/2788/resultse.png 来源

使用Mono.Simd的Mono在很大程度上通过手动优化的C ++来缩小性能差距,但C ++版本仍然是最快的。 但Mono目前处于2.6,可能会更接近,我希望如果.NET能够获得类似Mono.Simd的东西,那么它可能会非常具有竞争力,因为.NET和顺序C ++之间没有太大的区别。

您指定的所有因素可能都是针对您的特定任务通过手动内存/代码优化完成的。 但JIT编译器没有足够的关于您的域的信息来使代码最佳,因为您可以手动创建代码,并且只能应用常规优化规则。 因此,它会比C / C ++矩阵操作代码慢(但如果你想要它可以利用100%的CPU 🙂

解决SSE问题: 自J2SE 1.4.2起,Java正在使用SSE指令 。

java无法在矩阵乘法中与c竞争,一个原因是它检查每个数组访问是否超出了数组边界。 进一步java数学很慢,它不使用处理器sin(),cos()。