7

他のいくつかのレポートから、人々は通常、プレーンで基本的な JNI 呼び出しで約4 ~ 80 nsを取得することを読みました。

からJNI呼び出しが遅くなる原因は何ですか?

単純なネイティブ メソッドの場合、昨年、Windows デスクトップで平均 40 ns、Mac デスクトップで 11 ns の呼び出しが見つかりました。

JNIを使​​用したパフォーマンスの向上の可能性から?

ただし、JNI 呼び出しには約 30 ns かかることがよくあります。

JNI コードで単純なメソッドを呼び出すと (単純とは、int 型を返す time int の引数が 1 つだけであることを意味します)、50,000 ~ 80,000 ns の往復呼び出し時間 (System.nanoTIme で測定) が得られます。

VM の「ウォームアップ」を行い、タイミングを計る前に呼び出しを数百回実行しても、約2000 ~ 4000 ns (800 ~ 1000 以下) になります。(上記のように、他の人が 100 ns 未満と報告しているのを聞いたことがあります。頻繁に電話をかけると、それよりも 10 ~ 20 倍高くなります。)

これは通常の速度ですか?ネイティブ コードの呼び出しが非常に遅くなる原因は何ですか?

アップデート:

JNIEXPORT jint JNICALL Java_com_snap2d_gl_RenderControl_correctGammaNative
  (JNIEnv *env, jobject obj, jint pixel) {
    return X2D_correctGamma(pixel, 1.0f);
}

X2D_correctGamma(int,float) は、ピクセルのガンマ値を修正するメソッドです (投稿後にネイティブ コードを実装しました)。

Java ベンチマーク:

    for(int i = 0; i < 100; i++) {
        long t1 = System.nanoTime();
        correctGammaNative(0xFFF);
        long t2 = System.nanoTime();
        System.out.println(t2 - t1);
    }

それが「ウォームアップ」コードです。ほとんどの println は、最初の呼び出しから 800 ~ 1000 ns を読み取りました。

残念ながら、これはレンダリングで使用されることになっており、これを 1 秒間に何千回も呼び出すとフレーム レートが 1 FPS に低下するため、破棄する必要があるかもしれません。

システム情報:

同様の動作: JDK1.6.0_32 (64 ビット)、JDK1.7.0_04 (64 ビット)、および JRE1.7.0_10 (32 ビット)

Windows 7 64 ビット

16GBのRAM

i7-3770 クアッドコア CPU @ 3.4-3.9ghz

GNU GCC MinGW コンパイラ (32 ビットおよび 64 ビット)

4

2 に答える 2

7

これは通常の速度ですか?

いいえ。実際に JNI 呼び出しごとに 50,000 ~ 80,000 ns を取得している場合は、何かおかしなことが起こっています。

ネイティブ コードの呼び出しが非常に遅くなる原因は何ですか?

わかりません。それはほとんど何でもありえます。しかし、ネイティブ コードと Java コードを見せていただければ、より適切に説明できます。

私のお金は、JNI呼び出しの問題ではなく、これにあります。むしろ、それはあなたがベンチマークしている方法の成果物だと思います. Java ベンチマークが誤った結果を生成する原因となる可能性がある (または行わない) ことはたくさんあります。ベンチマーク コードを確認する必要があります。


OK、あなたのアップデートは、以前に報告されたタイミング (50,000-80,000 または 2000-4000) が正しくないか、無関係であることを示しています。以下を考えると、800 ~ 1000 ns のタイミングはもっともらしく聞こえます。

ベンチマークには 3 つの欠陥があると思います。

  • 数ナノ秒のオーダーで時間間隔を測定しようとしています。しかし、あなたの測定が考慮していないのは、への呼び出しにSystem.nanoTime()かなりの時間がかかるということです。必要なことは、呼び出しの各ペアの間に数千または数百万回の JNI 呼び出しを行うのにかかる時間を測定しSystem.nanoTime()、平均を計算して出力することです。

  • あなたのコードは、JNI 呼び出しの実行にかかった時間と呼び出し本体の実行にかかった時間を分けていません。(または、そうかもしれません...そして、あなたは私たちにそのコードを見せていません。)ガンマ補正には、JNI 呼び出しのオーバーヘッドよりもかなり長い時間がかかると思います。

  • ウォームアップが不十分です。JIT コンパイルが開始されるのに十分な時間コードを実行しているとは思えません。さらに、ベンチマーク コードが単一のメソッド呼び出しに限定されているという事実は、JIT コンパイラが実行されたとしても、 d メソッドの JIT コンパイル バージョンを呼び出してはいけません。ベンチマーク コードをメソッドに入れ、そのメソッドを繰り返し呼び出します。

于 2013-01-11T01:33:15.607 に答える
0

ウォーミングアップが短すぎる。~10.000 回の呼び出し後にメソッドがジットされます。さらに、ループ本体をメソッドに移動します。これは、「インプレース」無限ループジッティングと単一メソッドのジッティングには違いがあるためです。

于 2013-09-05T09:29:30.120 に答える