我最近开始徘徊于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毫秒)才能运行。所以,
非常感谢你。
编辑:df将为同一粒子返回无穷大,因此删除条件表达式不是一个选项。
1)嗯,我仍然是计算着色器的新手,但我认为是的。如果单个工作组内的不同调用为循环执行变量lenth,则某些线程可能已经完成,并且必须等到所有线程在该特定工作组内完成执行。之后,工作组可能会换成另一个未处理的工作组。
2)因为两个代码都不相同。相当于我的意思是相同的陈述。上面有2个循环。虽然下面有一个大循环,里面有一个“if”语句。所以我的猜测是If语句导致更高的运行时间。
如果你可以通过在数组poss
中的索引gid
中添加另一个向量来删除“If”语句,这样在gid
处理后添加到f
的向量是vec3(0,0,0)
,我认为它会改善你的执行时间。