gpt4 book ai didi

android - glsl编程架构哪一部分是 "really"并行执行?

转载 作者:行者123 更新时间:2023-11-29 17:56:38 26 4
gpt4 key购买 nike

我正在尝试使用 glsl 在 GPU 中实现图像处理算法,如高斯滤波、双边滤波。

我对哪一部分是“真正的”并行执行感到困惑。例如,我有一个 1280*720 的预览作为纹理。我不太确定哪个部分真正运行了 1280*720 次,哪个部分不是。

glsl代码的调度机制是什么?

我的高斯滤波代码是这样的:

#extension GL_OES_EGL_image_external : require
precision mediump float;
varying vec2 vTextureCoord;
uniform samplerExternalOES sTexture;
uniform sampler2D sTextureMask;

void main() {

float r=texture2D(sTexture, vTextureCoord).r;
float g=texture2D(sTexture, vTextureCoord).g;
float b=texture2D(sTexture, vTextureCoord).b;

// a test sample
float test=1.0*0.5;

float width=1280.0;
float height=720.0;

vec4 sum;

//offsets of a 3*3 kernel
vec2 offset0=vec2(-1.0,-1.0); vec2 offset1=vec2(0.0,-1.0); vec2 offset2=vec2(1.0,-1.0);
vec2 offset3=vec2(-1.0,0.0); vec2 offset4=vec2(0.0,0.0); vec2 offset5=vec2(1.0,0.0);
vec2 offset6=vec2(-1.0,1.0); vec2 offset7=vec2(0.0,1.0); vec2 offset8=vec2(1.0,1.0);

//gaussina kernel with sigma==100.0;
float kernelValue0 = 0.999900; float kernelValue1 = 0.999950; float kernelValue2 = 0.999900;
float kernelValue3 = 0.999950; float kernelValue4 =1.000000; float kernelValue5 = 0.999950;
float kernelValue6 = 0.999900; float kernelValue7 = 0.999950; float kernelValue8 = 0.999900;

vec4 cTemp0;vec4 cTemp1;vec4 cTemp2;vec4 cTemp3;vec4 cTemp4;vec4 cTemp5;vec4 cTemp6;vec4 cTemp7;vec4 cTemp8;



//getting 3*3 pixel values around current pixel
vec2 src_coor_2;
src_coor_2=vec2(vTextureCoord[0]+offset0.x/width,vTextureCoord[1]+offset0.y/height);
cTemp0=texture2D(sTexture, src_coor_2);
src_coor_2=vec2(vTextureCoord[0]+offset1.x/width,vTextureCoord[1]+offset1.y/height);
cTemp1=texture2D(sTexture, src_coor_2);
src_coor_2=vec2(vTextureCoord[0]+offset2.x/width,vTextureCoord[1]+offset2.y/height);
cTemp2=texture2D(sTexture, src_coor_2);
src_coor_2=vec2(vTextureCoord[0]+offset3.x/width,vTextureCoord[1]+offset3.y/height);
cTemp3=texture2D(sTexture, src_coor_2);
src_coor_2=vec2(vTextureCoord[0]+offset4.x/width,vTextureCoord[1]+offset4.y/height);
cTemp4=texture2D(sTexture, src_coor_2);
src_coor_2=vec2(vTextureCoord[0]+offset5.x/width,vTextureCoord[1]+offset5.y/height);
cTemp5=texture2D(sTexture, src_coor_2);
src_coor_2=vec2(vTextureCoord[0]+offset6.x/width,vTextureCoord[1]+offset6.y/height);
cTemp6=texture2D(sTexture, src_coor_2);
src_coor_2=vec2(vTextureCoord[0]+offset7.x/width,vTextureCoord[1]+offset7.y/height);
cTemp7=texture2D(sTexture, src_coor_2);
src_coor_2=vec2(vTextureCoord[0]+offset8.x/width,vTextureCoord[1]+offset8.y/height);
cTemp8=texture2D(sTexture, src_coor_2);

//convolution
sum =kernelValue0*cTemp0+kernelValue1*cTemp1+kernelValue2*cTemp2+
kernelValue3*cTemp3+kernelValue4*cTemp4+kernelValue5*cTemp5+
kernelValue6*cTemp6+kernelValue7*cTemp7+kernelValue8*cTemp8;

float factor=kernelValue0+kernelValue1+kernelValue2+kernelValue3+kernelValue4+kernelValue5+kernelValue6+kernelValue7+kernelValue8;

gl_FragColor = sum/factor;
//gl_FragColor=texture2D(sTexture, vTextureCoord);

}

此代码在我的手机 (galaxy nexus) 上以较低的 fps 运行纯预览。

但是如果我将代码的最后一部分更改为使用原始像素值直接输出,例如

    //gl_FragColor = sum/factor;
gl_FragColor=texture2D(sTexture, vTextureCoord);

它会运行得很快,并且 fps 与纯预览相同。

问题是:我为测试而写的东西一开始没用,比如:

float test=1.0*0.5;

执行了多少次?

其他部分如:

sum =kernelValue0*cTemp0+kernelValue1*cTemp1+kernelValue2*cTemp2+
kernelValue3*cTemp3+kernelValue4*cTemp4+kernelValue5*cTemp5+
kernelValue6*cTemp6+kernelValue7*cTemp7+kernelValue8*cTemp8;

刚改的时候不会跑1280*720次

gl_FragColor = sum/factor;

gl_FragColor=texture2D(sTexture, vTextureCoord);?

决定运行 1280*720 次的机制是如何决定的,当像素并行时,这是无用的?是自动完成的吗?

glsl 程序的架构、调度、它如何将数据组织到 GPU 以及其他方面?

我想知道我应该如何处理更复杂的操作,如双边滤波和内核大小,如 9*9 和每像素 9 次,而不是这个 3*3 高斯内核。

最佳答案

对于每个 fragment ,整个 fragment 着色器代码作为一个整体执行。如果没有对输出像素进行抗锯齿处理,或者对帧缓冲区的样本进行多重采样抗锯齿处理,则 fragment 近似。 fragment 到底是什么,OpenGL 规范没有详细说明,除了它是 fragment 阶段的输出,然后将其转换为帧缓冲区位平面上的值。

The rasterizer produces a series of framebuffer addresses and values using a two-dimensional description of a point, line segment, or polygon. Each fragment so produced is fed to the next stage that performs operations on individual fragments before they finally alter the framebuffer. These operations include

[OpenGL-3.3 核心规范,第 2.4 节]


would not run 1280*720 times just when I change

gl_FragColor = sum/factor;

to

gl_FragColor=texture2D(sTexture, vTextureCoord);?

除法是一项成本高昂且复杂的操作。由于内核的总和是一个常数,并且每个 fragment 都不会改变,因此您不应该在着色器中对其进行评估。在 CPU 上对其进行评估,并提供 1./factor 作为统一变量(对于所有 fragment 都是一个常数),然后将其与 sum 相乘,这比除法快得多。

你的高斯核实际上是一个 3×3 矩阵,在 GLSL 中有专门的类型。您执行的计算可以根据点积(数学上正确的术语应该是标量或内积)重写,GPU 有专门的加速指令。

此外,您不应该将纹理的组件拆分为单独的 float 。

总而言之,您在代码中设置了很多减速带。

关于android - glsl编程架构哪一部分是 "really"并行执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18848209/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com