我正在使用GLSL着色器编写GPGPU程序,并尝试为N体碰撞检测算法进行一些优化。一个是快速执行“快速”操作。检查以确定两个对象是否在同一个球场中。我的想法是迅速取消许多可能性,以便我只需要对少数几个物体进行更准确的碰撞测试。如果快速检查确定他们可能会发生碰撞,则会执行准确的检查。
对象是圆圈(或球体)。我知道他们中心的位置和他们的半径。快速检查将查看它们的方形(或立方体)边界框是否重叠:
//make sure A is to the right of and above B
//code for that
if(A_minX > B_maxX) return false; //they definitely don't collide
if(A_minY > B_maxY) return false; //they definitely don't collide
if(length(A_position - B_position) <= A_radius + B_radius){
//they definitely do collide
return true;
}
我的问题是,执行此快速检查的开销(确保A和B的顺序正确,然后检查其边界框是否重叠)是否会比调用length()
并比较反对它们的组合半径。
了解GLSL中各种数学运算的相对计算成本是有用的,但我不太确定如何根据经验发现它们或者这些信息是否已经在某处发布。
答案 0 :(得分:0)
虽然我们关注的是成本主题,但您不需要在此处使用两个分支机构。您可以测试组件测试的结果。因此,可以使用any (greaterThan (A_min, B_max))
将其折叠为单个测试。一个好的编译器可能会解决这个问题,但如果您自己考虑数据并行性,它会有所帮助。
成本都是相对的。 15年前,执行length (...)
所做的算术工作使得你可以在更短的时间内完成立方体贴图纹理查找 - 在更新的硬件上你疯了,因为计算比内存更快。
总而言之,线程差异可能比指令或内存吞吐量更多地成为瓶颈。也就是说,如果并行运行的两个着色器调用在着色器中采用不同的路径,则可能会引入不必要的性能损失。底层硬件架构意味着曾经是优化安全的东西可能不会在将来出现,甚至可能导致优化尝试损害性能。
答案 1 :(得分:0)
通过比较值的平方,可以避免使用平方根(length()
函数隐式需要)。
测试可能如下所示:
vec3 vDiff = A_position - B_position;
float radSum = A_radius + B_radius;
if (dot(vDiff, vDiff) < radSum * radSum) {
return true;
}
这将它简化为单个测试,但仍然只使用简单有效的操作。