OpenGL Compute着色器可以更快地分离循环

问题描述 投票:0回答:1

我最近开始徘徊于GPGPU,并编写了一个MD模拟程序作为课程作业。从其他粒子计算力的部分如下。

vec3 pn = poss[gid].xyz;
vec3 f = vec3(0, 0, 0);
for (uint i = 0; i < gid; i++) {
    f += df(pn, poss[i].xyz);
}
for (uint i = gid+1; i < num; i++) {
    f += df(pn, poss[i].xyz);
}
fors[gid].xyz = f;

在我的GTX960上运行带有32000个实例(500个线程)的代码需要50ms。

我的讲师建议合并2个循环,因为线程同步(?)会导致执行时间过长。所以我把它改成如下。

for (uint i = 0; i < num; i++) {
    if (i != gid) f += df(pn, poss[i].xyz);
}

但是,这需要65毫秒(长15毫秒)才能运行。所以,

  1. 对于现代硬件(GL4.3 +)来说,对于本地线程中可变长度的循环,仍然需要在继续之前完成所有内容,并且
  2. 如果是这样,为什么第二个代码会变慢?

非常感谢你。

编辑:df将为同一粒子返回无穷大,因此删除条件表达式不是一个选项。

c++ opengl compute-shader
1个回答
0
投票

1)嗯,我仍然是计算着色器的新手,但我认为是的。如果单个工作组内的不同调用为循环执行变量lenth,则某些线程可能已经完成,并且必须等到所有线程在该特定工作组内完成执行。之后,工作组可能会换成另一个未处理的工作组。

2)因为两个代码都不相同。相当于我的意思是相同的陈述。上面有2个循环。虽然下面有一个大循环,里面有一个“if”语句。所以我的猜测是If语句导致更高的运行时间。

如果你可以通过在数组poss中的索引gid中添加另一个向量来删除“If”语句,这样在gid处理后添加到f的向量是vec3(0,0,0),我认为它会改善你的执行时间。

© www.soinside.com 2019 - 2024. All rights reserved.