簡體   English   中英

使用JNI可能會提高性能?

[英]Possible increase of performance using JNI?

一兩年前,我創建了一個用Java編寫的程序來模擬n體問題。 最近,我已經瘋狂地將程序重寫為分布式程序,以便能夠以更高的精度模擬更大的質量。

正如預期的那樣,對舊程序進行分析表明,大約90%的程序用於計算浮點型值。 如果我沒記錯的話C / C ++比算術運算時更快,尤其是浮點型計算。

無論如何,這是實際的問題:)

通過使用JNI,我可以期望速度的增加等於用C / C ++編寫的程序(用於計算)還是JVM會降低速度?

Java中大多數浮點運算大約需要1 ns,因此我不確定它們在C ++中的速度會有多快。

但是,JNI調用通常需要大約30 ns,因此除非您每次調用執行大量浮點運算,否則您將花費​​比保存更多的成本。

正如以下微基准所暗示的那樣,一旦代碼熱身,每個操作都是亞納秒。

如果您希望速度更快,可以使用多個內核並使其速度提高4倍或更快。

public static void main(String[] args) throws Exception {
    int length = 200000;
    double[] a = fill(new double[length]);
    double[] b = fill(new double[length]);
    double[] c = fill(new double[length]);
    double[] x = new double[length];

    for (int i = 0; i < 10; i++)
        testTime(length, a, b, c, x);
}

private static void testTime(int length, double[] a, double[] b, double[] c, double[] x) {
    long start = System.nanoTime();
    for (int i = 0; i < length; i++)
        x[i] = a[i] * b[i] + c[i];
    long time = System.nanoTime() - start;
    System.out.printf("Average time per double operation was %.1f ns%n", time / 2.0 / length);
}

private static double[] fill(double[] doubles) {
    for (int i = 0; i < doubles.length; i++)
        doubles[i] =  Math.random();
    return doubles;
}

版畫

Average time per double operation was 10.9 ns
Average time per double operation was 17.9 ns
Average time per double operation was 1.7 ns
Average time per double operation was 1.0 ns
Average time per double operation was 0.9 ns
Average time per double operation was 0.8 ns
Average time per double operation was 0.9 ns
Average time per double operation was 0.8 ns
Average time per double operation was 1.0 ns
Average time per double operation was 0.9 ns

我想這個答案: JNI Performance也適用於此。 如果你在每次性能受到影響時多次調用JNI。 如果您為重度計算調用JNI,那么C優化代碼應該執行得更快。

我實際上最近測試了分形生成(Mandelbrot)與使用Java編寫的相同代碼,然后移植到C,令我驚訝的是,我在使用JNI方法時觀察到計算速度略有下降。 我只能通過一件事來解釋這個現象:如果你使用c代碼,你就無法利用HotSpot的優化來進行可重復的計算。

您可以在以下網址查看示例代碼: http//code.google.com/p/frgenjava/

編輯:在我描述的情況下,當使用JNI時,我忽略了JNI調用的開銷,調用大約需要20ns,即使C執行得更慢。

性能問題最重要的是測試和測試。 您已經聽說過C ++在浮點數方面比java更好。 好的可能是這種情況。 但如果沒有替補來展示這種實際差異,這不值一分錢。 這可能是錯誤的。

實際上,現代java使用JIT。 那是什么 ? 好吧,我們都知道java使用字節碼,並解釋字節碼。 這是真的和錯誤的。 實際上,大量使用的代碼會動態編譯為針對您的平台優化的本機代碼。 JIT甚至可以通過使用執行統計信息在C / C ++中執行不可能的優化。

現在Java和JVM被廣泛接受為一個非常快速有效的平台。 人們開始在重型計算領域真正使用它並取得了相當大的成功。 在網格上部署也更容易。

最近的基准測試往往表現出類似於C / C ++的性能(例如http://blogs.oracle.com/amurillo/entry/java_vs_c

那么你會從JNI獲得並只是移植到C ++。 我會說不,或收獲很少。 (但如果你想確定,再次測試)。 沒有優化它,C ++版本可能會更慢。

您是否可以通過使用JNI並使用優化的匯編代碼(包括SEE指令)獲得大幅改進? 如果你以正確的方式做到,肯定是的。 這需要很多工作台,專業知識和時間。

我不能評論Java算術運算的速度,但我知道JNI會直接調用你的C ++代碼,所以你會得到原生速度,是的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM