0

GraalVM 内で Java から R コードを呼び出した場合 (GraalVM の polyglot 関数を使用)、R コードと Java コードは同じ Java スレッドで実行されますか (つまり、OS または Java スレッド間の切り替えはありませんか?)メモリ/ヒープ」スペース?つまり、以下のコード例 ( https://www.baeldung.com/java-r-integrationから取得)

public double mean(int[] values) {
    Context polyglot = Context.newBuilder().allowAllAccess(true).build();
    String meanScriptContent = RUtils.getMeanScriptContent(); 
    polyglot.eval("R", meanScriptContent);
    Value rBindings = polyglot.getBindings("R");
    Value rInput = rBindings.getMember("c").execute(values);
    return rBindings.getMember("customMean").execute(rInput).asDouble();
}

呼び出しrBindings.getMember("c").execute(values)により、値オブジェクト (int の配列) がコピーされますか? それとも、GraalVM はそれを同じメモリ空間へのポインタと見なすほどスマートなのでしょうか? コピーの場合、コピー時間は、通常の Java clone() 操作の場合と同じ (または類似、つまり 20% 以内) ですか? 最後に、ポリグロット関数 (この場合は R で実装された customMean) の呼び出しには、ネイティブ Java 関数の呼び出しと同じオーバーヘッドがありますか? おまけの質問: GraalVM JIT コンパイラは、レイヤー全体でコンパイルすることさえできますか?

final long sum = IntStream.range(0,10000)
.stream()
.map(x -> x+4)
.map(x -> <<<FastR version of the following inverse operation: x-4 >>>)
.sum();

GraalVM コンパイラは、通常の Java JIT コンパイラと同じくらいスマートで、上記のステートメント全体が 2 つのマップ操作なしで簡単に記述できることに気付くでしょうか (これらは互いに相殺されるため)。

参考までに: ここで特定した問題が解決されたら、GraalVM を使用して Java コードと R コードの両方を実行することを検討しています(オラクルの主張にもかかわらず、通常の R と比較して FASTR (つまり、R の GraalVM バージョン) が 10 倍 *遅い*のはなぜですか? 40 倍 *高速*? ) であり、動機の 1 つは、Java から R を呼び出す (RServe() を使用する) 時間がネットワーク IO に費やされる時間の 50% をなくすことです (Java は TCP/IP および RServe を介して RServer と通信するため)。およびJavaは異なるスレッドとメモリ空間などにあります)

4

1 に答える 1

1

R コードと Java コードを同じ Java スレッドで実行します。また、同じ「メモリ/ヒープ」スペースですか?

はい、はい。GraalVM VisualVM を使用してヒープを検査することもできます。標準の Java ビューを提供し、FastR の内部表現のインスタンスをRIntVector他の Java オブジェクトの残りの部分と混合して見ることができます。また、R ビューを提供し、整数ベクトル、リスト、環境、 ...

rBindings.getMember("c").execute(values) を呼び出すと、values オブジェクト (int の配列) がコピーされますか?

一般的にはい: ほとんどのオブジェクトは R にそのまま渡されます。R 内では、次の 2 つの選択肢があります。

  • それらを具体的な型、つまり に明示的に変換しますas.integer(arg)。これはコピーを作成しませんが、その値を R の値セマンティクスを含む「ネイティブ」R 型としてどのように扱うかを R に明示的に伝えます。
  • オブジェクトがいくつかの R ビルトインに渡されると適用されるデフォルトのルールのままにしておきます。たとえば、int[]整数ベクトルとして扱われます (ただし、場合によっては、リストとして扱うことも合理的であることに注意してください)。ここでもコピーはありません。また、オブジェクト自体はその参照セマンティクスを保持します。

ただし、FastR でコピーを作成する必要がある場合があります。

  • 一部の組み込み関数は、まだ外部オブジェクトを処理できません
  • R 言語は、その値のセマンティクス、引数の強制などのために、暗黙的にベクトルをコピーすることがよくあります。
  • ベクトルがネイティブ R 拡張機能に渡されるとき、そのデータをオフ ヒープ メモリに移動する必要があります。

非常に大きなベクトル、たとえば GB のデータがある場合は、通常の R であっても非常に注意する必要があります。 FastR ベクターも。

最後に、ポリグロット関数 (この場合は R で実装された customMean) の呼び出しには、ネイティブ Java 関数の呼び出しと同じオーバーヘッドがありますか?

ほとんどの場合、関数を取り込んで周囲の Java コードにインライン化することはできません(+)。呼び出し自体は、通常の Java 呼び出しと同じくらい高速です。あなたが与える例について:R関数はインライン化できないため、提案どおりに最適化できません(+)。ただし、両方の機能が純粋なJavaコードであっても、あなたが提案するように、どのコンパイラーもこれを最適化できるかどうかは非常に懐疑的です。そうは言っても、そうです。Java <-> R 境界 (+) を越えてコードをインライン化することが不可能であるため、コンパイラーが最適化できるいくつかのこと (よく分析できる無駄な計算を排除するなど) は機能しません。

(+) Espresso (Java on Truffle) で Java コードを実行しない限り、Context API を使用せず、Espresso の相互運用サポートを使用することになります。

于 2022-02-02T20:50:58.690 に答える