研究了一个多星期的GPGPU,学了ARB(GPU assembly language)和GLSL,遇到不少bug和纠结的问题.现在总结一下.
1.GPU的计算速度很快,如果你需要的数值可以通过少量计算求出来,那千万不要预先把它们存在纹理里读取,哪怕它们需要被重复利用N多次.一次纹理采样所耗费的时间远远大于你做10次甚至20次浮点计算的时间,尤其是在三维纹理中,效率就更低了.
GPU Gems2的第32.1.2节中所讲的,当我们的片段程序从纹理中读取一个数据的时候,这个过程交给纹理子系统来完成,为了掩盖这段时间(或者延迟),GPU会开始处理下一个片段,直到数据读取回来之后再继续处理原来的片段.如果要让我们的程序的性能取决于我们的计算而不是显存的话,我们的片段程序就必须包含足够的计算来掩盖纹理读取的时间.
2.对于一个纹理,GL_TEXTURE_MIN_FILTER和GL_TEXTURE_MAG_FILTER的设置,对采样速度有很大影响.GL_NEAREST的速度是GL_LINEAR的两倍以上.是否需要线性插值就看程序的需要了.还是那句话,能算则算,不要在纹理上采样.
3.不知道在GPU的其他通用平台(如CUDA和OPENCL)上是什么情况,在使用OPENGL做GPGPU编程的时候,我发现一个有趣的现象,无论使用ARB还是GLSL,compiler都会自动忽略对输出结果无影响的语句.虽然这个结论是我自己的猜想,不一定对.我学习GPGPU的时间还不够长,资料也没看很多,不知道有没有什么资料上有讲到这个问题.这个结论可以从下面的GLSL代码体现出来.
Example 1:
for(coord.x=0.0;coord.x<R;coord.x=coord.x+1.0) //increase coord.x, coord.y is constant, R=100.0
{
off=texture2DRect(texoff,coord).rgb;
fpos=pos-off; //the value of pos is known
force=texture3D(texforce,fpos).rgb;
fresult=fresult+force;
}
//gl_FragColor.rgb=fresult+texture2DRect(texpre,geopos.st).rgb; //use about 50 sec
//gl_FragColor.rgb=fpos; //use only 6 sec
上面注释掉的两行代码,实际运行的时候我只注释其中一条.两者的计算时间相差了8倍之多.
for循环里面的代码不动,如果返回结果用第一条语句,"force"和"fpos"的值实际上都关系到了fresult的取值.而第二条语句,返回的是fpos的值,只和"off"还有第一条采样语句有关.
当我运行下面的代码的时候,本以为没有了force的采样和fresult的加法,会更快.结果却得到了同样的计算时间,6秒.
Example 2:
for(coord.x=0.0;coord.x<R;coord.x=coord.x+1.0) //increase coord.x, coord.y is constant, R=100.0
{
off=texture2DRect(texoff,coord).rgb;
fpos=pos-off; //the value of pos is known
//force=texture3D(texforce,fpos).rgb;
//fresult=fresult+force;
}
gl_FragColor.rgb=fpos;
所以我只能是这么理解.在Example 1里, 与fpos无关的两条语句实际上并没有执行,否则为什么Example 1里两个返回语句的效率相差那么多呢?
以上纯属猜测,还要去请教高手才知道为什么了.
不过这个情况也只出现在测试中啦..一般也不会有人写无关的语句进去..但是这个问题依然很有趣..
至于真正要返回fresult的速度为什么那么慢,主要原因还是在采样上,尤其是在两个不同的纹理上采样,第一个纹理的采样值用于计算第二个纹理采样的坐标.这个地方很耗费时间.
4.我用的N卡,N卡的驱动上有监视狗,会检测每个shader的运行时间,避免有些shader进入死循环.当shader的运行时间过长,也会被它强制关闭,然后系统会出现短暂黑屏,之后恢复正常,NV驱动提示停止响应并已恢复正常.所以如果一个shader需要运行很长时间的话,只能把它分割成几个shader来跑,中间结果就必须想办法保存咯,比如pre output/next input.
不知道A卡上是什么样子.改天拿块试试.
5.ARB的效率明显比GLSL快~^0^这是汇编的好处~~估计也会比CUDA和OPENCL快点..就好比CPU上编程用汇编会比C++高效.
以上是一个星期来纠结过的问题,尤其是采样这个问题上对我的程序影响极大.只能怪自己对GPU了解还太浅,要熟练掌握GPGPU还要继续好好花点功夫了~^_^~