2017-03-28 7 views
1

제목과 정확히 같습니다.Android 렌더 스크립트는 GPP에서 실행되지 않습니다

나는 병렬 처리 된 이미지 생성/처리 알고리즘을 사용하고 싶습니다. 이는 일종의 펄린 노이즈 구현입니다. 나는 질감 쿼드에 조각 쉐이더를 통해 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); 
} 

이 정확한 알고리즘은 적어도 30 프레임으로 실행됩니다.

RenderScript를 실행하기위한 오버 헤드는 x 및 y 정규화 된 좌표를 반환하여 간단한 비트 맵을 작성하여 계산 한 최대 100ms 여야합니다.

즉, gpu를 사용할 경우 10 초가되지 않습니다.

내가 가진 RenderScript을 사용하고 코드 :이 도움 (https://stackoverflow.com/a/14942723/4420543)를 사용에서, FilterScript로 변경하는 경우

// 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를 사용하여 실행할 수 있습니까? 대부분의 GPU는 전 정밀도 부동 소수점 연산을 지원하지 않기 때문에

#pragma rs_fp_relaxed 

rs_fp_full은 CPU에서 실행되는 스크립트를 강제 할 것이다.

+0

이 라인을 비활성화하는 문제는 노이즈 구현시 높은 (부동 소수점) 정밀도가 필요하며 GPU에서 '불량'그림을 렌더링하는 대신 GPU를 지원하지 않는 경우에만 장치가 CPU를 사용하는 것이 좋습니다. . – andras

+0

"rs_fp_relaxed"는 OpenGL의 고정밀도가 낮은 것은 아닙니다. –

+0

여기서 우리는 계산 정밀도에 대해 이야기하고 있습니다. "rs_fp_relaxed"는 여전히 32 비트 부동 소수점이며, 단지 denorm과 같은 특정 수학 연산을 완화합니다. 실제로 GL 쉐이더는 모바일에서도 비슷한 일을합니다.그게 당신을 위해 작동하는지 확인하기 위해 당신이 테스트 장치에 그것을 밖으로 시도하는 것이 좋습니다. –

0

나는 당신의 추측에 동의 할 수있다.

Nexux 7 (2013, JellyBean 4.3)에서 필자는 유명한 만델 브로 세트를 계산하기 위해 렌더 스크립트와 필터 스크립트를 각각 작성했습니다. 동일한 작업 (32 비트 부동 소수점 사용)을 수행하는 OpenGL 조각 쉐이더와 비교할 때 스크립트는 약 3 번 보다 느림입니다. OpenGL은 rendererscript (및 filterscript!)가없는 GPU를 사용한다고 가정합니다.

그런 다음 카메라 미리보기 변환 (NV21 형식 -> RGB)과 렌더 스크립트, 필터 스크립트 및 ScriptIntrinsicYuvToRGB를 각각 비교했습니다. 여기 내장 함수는 자체 작성 스크립트보다 약 4 배 빠릅니다. 다시 renderscript와 filterscript 사이의 성능 차이는 없습니다. 이 경우에는 자체 작성 스크립트가 내장 스크립트가 GPU를 사용하는 경우에만 CPU를 다시 사용한다고 가정합니다.