2017-03-28 17 views
1

タイトルのとおりです。Androidレンダスクリプトは決してgpuで動作しません

私は、使用したい並列化画像作成/処理アルゴリズムを持っています。これはパーリンノイズの実装の一種です。比較として

// Logging is never used here 
#pragma version(1) 
#pragma rs java_package_name(my.package.name) 
#pragma rs_fp_full 

float sizeX, sizeY; 
float ratio; 

static float fbm(float2 coord) 
{ ... } 

uchar4 RS_KERNEL root(uint32_t x, uint32_t y) 
{ 
float u = x/sizeX * ratio; 
float v = y/sizeY; 

float2 p = {u, v}; 

float res = fbm(p) * 2.0f; // rs.: 8245 ms, fs: 8307 ms; fs 9842 ms on tablet 

float4 color = {res, res, res, 1.0f}; 
//float4 color = {p.x, p.y, 0.0, 1.0}; // rs.: 96 ms 

return rsPackColorTo8888(color); 
} 

Iがテクスチャクワッドにフラグメントシェーダを介してGPU上に実装する場合、この正確なアルゴリズムは、少なくとも30のFPSで実行されます。

RenderScriptを実行するためのオーバーヘッドは、xとyの正規化座標を返すことによって単純なビットマップを作成して計算した最大100 msです。

つまり、gpuを使用する場合は、10秒にはならないことを意味します。

私はとのrenderScriptを使用していますコード:私はFilterScriptに変更した場合は、このヘルプ(https://stackoverflow.com/a/14942723/4420543)を使用してから、私は数百ミリ秒サポートライブラリの場合はさらに悪化し、二重の時間について取得

// The non-support version gives at least an extra 25% performance boost 
import android.renderscript.Allocation; 
import android.renderscript.RenderScript; 

public class RSNoise { 

    private RenderScript renderScript; 
    private ScriptC_noise noiseScript; 

    private Allocation allOut; 

    private Bitmap outBitmap; 

    final int sizeX = 1536; 
    final int sizeY = 2048; 

    public RSNoise(Context context) { 
     renderScript = RenderScript.create(context); 

     outBitmap = Bitmap.createBitmap(sizeX, sizeY, Bitmap.Config.ARGB_8888); 
     allOut = Allocation.createFromBitmap(renderScript, outBitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE); 

     noiseScript = new ScriptC_noise(renderScript); 
    } 

    // The render function is benchmarked only 
    public Bitmap render() { 
     noiseScript.set_sizeX((float) sizeX); 
     noiseScript.set_sizeY((float) sizeY); 
     noiseScript.set_ratio((float) sizeX/(float) sizeY); 

     noiseScript.forEach_root(allOut); 

     allOut.copyTo(outBitmap); 

     return outBitmap; 
    } 
} 

非支持の場合にはより悪い。精度は結果に影響しませんでした。

私はstackoverflowに関するすべての質問もチェックしましたが、それらのほとんどは時代遅れで、いくつかの新しいデバイスの中でnexus 5(7.1.1 osバージョン)でも試しましたが、まだ問題は残ります。

したがって、RenderScriptはいつGPUで実行されますか?誰かが私にGPU実行RenderScriptの例を与えることができれば十分でしょう。

答えて

2

rs_fp_fullの代わりにrs_fp_relaxedを実行してみることはできますか?

#pragma rs_fp_relaxed 

ほとんどのGPUは完全精度浮動小数点演算をサポートしていないため、rs_fp_fullはCPUでスクリプトを実行します。

+0

この行を無効にする問題は、ノイズの実装に高い(浮動小数点)精度が必要で、gpuで「不良」画像をレンダリングするのではなく、gpuをサポートしていない場合にのみデバイスがCPUを使用する方が良いでしょう。 – andras

+0

"rs_fp_relaxed"は、OpenGLの精度が "精度が低い"という意味ではありません。 –

+0

ここでは、計算精度について説明します。 "rs_fp_relaxed"はまだ32bit浮動小数点数ですが、denormのような特定の数学演算を緩和します。実際にGLシェーダはモバイルで同様のことを行います。テスト用デバイスで試してみることをお勧めします。 –

0

私はあなたの推測に同意することができます。

Nexux 7(2013、JellyBean 4.3)では、それぞれ、レンダスクリプトとフィルタスクリプトを書いて、有名なマンデルブロセットを計算しました。 同じことをするOpenGLフラグメントシェーダ(すべて32ビット浮動小数点数を使用)と比較して、スクリプトは約3倍遅いでした。 OpenGLはレンダスクリプト(とfilterscript!)ではGPUを使用しないと仮定します。

次に、レンダスクリプト、フィルタスクリプト、ScriptIntrinsicYuvToRGBでカメラプレビュー変換(NV21フォーマット - > RGB)を比較しました。 組み込み関数は、自己記述スクリプトより約4倍高速です。 もう一度、レンダスクリプトとフィルタスクリプトの間にパフォーマンスの違いは見られません。このケースでは、IntrinsicがGPUを使用している場合に限り、自分で書かれたスクリプトがCPUを再び使用すると仮定します(あまりにも?)。

関連する問題