2011-10-12 49 views
4

我目前正在开发基于Java的网络编码库(http://en.wikipedia.org/wiki/Network_coding)。这非常耗费CPU资源,因此需要一些优化编码阶段的帮助。我实际上做的是我创建原始数据的随机线性组合,其中加法是XOR并且乘法是伽罗瓦域乘法(在GF(2^16)中)。提高网络编码编码的性能

我已经尽我所能地进行了优化。例如我使用这样的技巧:http://groups.google.com/group/comp.dsp/browse_thread/thread/cba57ae9db9971fd/7cd21eec39ddae1a?hl=en&lnk=gst&q=Sarwate+Galois#7cd21eec39ddae1a使乘法更快。

因此,我正在寻找关于如何进一步优化这方面的提示。这很难描述,因为我用过的分析器并没有给出任何关于哪个操作最昂贵的提示(例如它是数组查找还是XOR)。所以我现在正在随机尝试不同的想法,并测试它是否会改善整体性能。

更具体地说,我需要在帮助改善一些潜在领域是:

  • 我怎样才能确保Java可以跳过边界检查的阵列的操作?
  • 如何检索HotSpot完成优化后实际执行的字节码?

这是算法的核心。这可能很难从背景中理解,但如果您看到我正在做的任何不必要的昂贵操作,请让我知道!

int messageFragmentStart = 0; 
int messageFragmentEnd = fragmentCharSize; 

int coefficientIndex = fragmentID * messageFragmentsPerDataBlock; 
final int resultArrayIndexStart = fragmentID * fragmentCharSize; 

for (int messageFragmentIndex = 0; messageFragmentIndex < messageFragmentsPerDataBlock; messageFragmentIndex++) { 
    final int coefficientLogValue = coefficientLogValues[coefficientIndex++]; 
    int resultArrayIndex = resultArrayIndexStart; 
    for (int i = messageFragmentStart; i < messageFragmentEnd; i++) { 
     final int logSum = coefficientLogValue + logOfDataToEncode[i]; 
     final int messageMultipliedByCoefficient = expTable[logSum];       
     resultArray[resultArrayIndex++] ^= messageMultipliedByCoefficient; 
    } 
    messageFragmentStart += fragmentCharSize; 
    messageFragmentEnd = Math.min(messageFragmentEnd + fragmentCharSize, maxTotalLength); 
} 

回答

2

您不能让Java放弃边界检查,如其在JLS中指定的那样。但是在大多数情况下,只要边界检查很简单(例如i < array.length),JIT就可以避免这种情况 - 如果没有,则无法避免它(好吧,我假设可以使用不安全的对象?)。

对于你的第二个问题有this这里应该满足的目的就好。

但无论如何,从你的代码看来,这个问题似乎是微不足道的矢量化和可悲的是JVM不是很擅长它/做它。因此,如果使用编译内在函数(甚至可以尝试ICC/GCC的自动矢量化)在c/C++中实现相同的代码,可能会导致一些非常明显的加速 - 假设我们没有完全限制内存。所以我会在C++中实现它,并使用JNI仅供参考。

+0

谢谢!我尝试使用PrintAssembly,但我收到以下错误消息:“无法加载hsdis-amd64.dll;库无法加载; PrintAssembly被禁用”。任何想法在哪里我可以得到这个DLL的持有? – Yrlec

+0

没关系。我更改为JDK 7(x86),并在http://classparser.blogspot.com/2010/03/hsdis-i386dll.html找到了该dll。 – Yrlec