我正在寻找一种算法来测试2个线段是否以GPU友好的方式相交。线段是2D。虽然网上讨论了许多算法来实现这一点,但我所看到的所有算法都使用了大量的分支指令。在CPU上,这不是一个问题。但是,在GPU上,许多分支指令会破坏性能。
有没有人知道这个环境的好算法?任何样本伪代码,CUDA代码,OpenCL代码或DirectCompute计算都将受到赞赏。
关注
如果有人感兴趣,这(基本上)是我最终的结果。我把它修剪下来,所以它更像是伪代码而不是OpenCL C,但希望它能得到满足。
__kernel void findCrossingLines(__global float2 p1, __global float2 p2,
__global float2 p3, __global float2 p4,
__global bool* output)
{
int result = 0;
float2 A = p2;
float2 a = p2 - p1;
float2 B = p4;
float2 b = p4 - p3;
float2 c = B - A;
float2 b_perp = (float2)(-b.y, b.x);
float numerator = dot(b_perp, c);
float denominator = dot(b_perp, a);
bool isParallel = (denominator == 0.0f);
float quotient = numerator / denominator;
float2 intersectionPoint = (float2)(quotient * a.x + A.x, quotient * a.y + A.y);
*output = (!isParallel &&
intersectionPoint.x >= min(p1.x, p2.x) &&
intersectionPoint.x >= min(p3.x, p4.x) &&
intersectionPoint.x <= max(p1.x, p2.x) &&
intersectionPoint.x <= max(p3.x, p4.x) &&
intersectionPoint.y >= min(p1.y, p2.y) &&
intersectionPoint.y >= min(p3.y, p4.y) &&
intersectionPoint.y <= max(p1.y, p2.y) &&
intersectionPoint.y <= max(p3.y, p4.y));
}
答案 0 :(得分:4)
这不在我的专业领域,但NVIDIA CUDA论坛上的以下主题讨论了这个主题,并包含一些可能提供有用起点的代码:
http://forums.nvidia.com/index.php?showtopic=180839
请注意,代码不必是完全无分支的,以便在NVIDIA GPU上高效。该体系结构支持预测以及“选择”类型指令(类似于C / C ++中的三元运算符),并且编译器非常擅长将本地分支映射到那些无分支结构。我建议使用cuobjdump检查生成的机器代码,这样你就可以准确地知道实际使用了多少分支。