【发布时间】:2026-01-16 01:25:01
【问题描述】:
我是 ocl 编程的新手。
我有 200 万个多边形(每个 4 行 - 对于这个例子 - 但它是变体),我需要找到与 1000 个椭圆的交点。
我需要知道每个椭圆是否至少与其中一个多边形相交。
为此,我创建了一个包含所有点的多边形缓冲区和椭圆缓冲区。
我的输出缓冲区是 1000 个项目 int 在所有项目中设置为 0。并且内核将根据椭圆索引在正确的索引中设置1(当他找到交集时)。
我使用全局 - 2 dim, {2million, 1000} 运行内核。
__kernel void polygonsIntersectsEllipses( __global const Point* pts,
__global const Ellipse* ellipses,
__global int* output)
{
int polygonIdx = get_global_id(0);
int ellipseIdx = get_global_id(1);
if (<<isIntersects>>) {
output[ellipseIdx] = 1;
}
}
问题是一旦其中一个多边形与椭圆相交,我就不需要计算其余的多边形。
我尝试在交叉点测试之前检查output[ellipseIdx] != 0,但性能并没有太大变化。
我尝试过做单一的暗淡全局 - 给出 1000 个(椭圆)并在内核中运行数百万个多边形并在我找到一个时停止,但仍然没有太大变化。
我做错了吗?我可以加快这个操作吗? 有什么建议吗?
编辑
使用@Moises 的提示并进行大量研究,我已将代码更改为单维运行 200 万次。使用小组工作项目。将我所有的结构更改为本机类型,跳过模数运算。基本上,我可以将数据从全局复制到私有/本地内存,我做到了。
我的本地大小是我的设备CL_DEVICE_MAX_WORK_GROUP_SIZE,在我的 cpu&gpu 中它是 1024,所以在一次运行中我覆盖了我所有的 1000 个椭圆。
主机端
size_t global = 1999872; // 2 million divided by 1024 - for the test
size_t local = 1024;
我的代码现在是这样的
__kernel void polygonsIntersectsEllipses( __global const float4* pts,
__global const float4* ellipses,
int ellipseCount,
__local float4* localEllipses,
__global int* output)
{
// Saving the ellipses to local memory
int localId = get_local_id(0);
if (localId < eCount)
localEllipses[localId] = ellipses[localId];
barrier(CLK_LOCAL_MEM_FENCE);
// Saving the current polygon into private memory
int polygonIdx = get_global_id(0);
float2 private_pts[5];
for (int currPtsIdx = 0; currPtsIdx < 4; currPtsIdx++)
{
private_pts[currPtsIdx] = pts[polygonIdx * 4 + currPtsIdx];
}
// saving the last point as first so i will not use modulus for cycling, in the intersection algorithm
private_pts[4] = private_pts[0];
// Run over all the ellipse in the local memory including checking if already there is an output
for (int ellipseIdx = 0; ellipseIdx < ellipseCount && output[ellipseIdx] == 0; ++ellipseIdx) {
if (<<isIntersects Using localEllipses array and private_pts>>) {
output[ellipseIdx] = 1;
}
}
}
结果
CPU 没有太大改进 - 更改后速度提高了 1.1。
GPU - 快 6.5 倍(我很兴奋)
还有什么地方可以改进吗? 提醒一下,一旦其中一个多边形与椭圆相交,我们就不需要检查其余的多边形。我怎么做 ?我询问输出值的技巧并没有真正奏效——无论有没有它,性能都是一样的
【问题讨论】:
标签: opencl