我想通过GPU计算点云中每个点的最近邻居。 我的数据集如下:
<number of points in column>
<number of columns>
x y z
x y z
z y z
... ... ...
将近20 ^ 6分。
我正在使用vector<PointXYZ> Input;
来存储数据
class PointXYZ
{
public:
PointXYZ();
~PointXYZ();
PointXYZ(float X, float Y, float Z) : x(X), y(Y), z(Z) {};
float x;
float y;
float z;
};
读取数据处于for循环中,它将忽略没有信息的点(x == 0 && y == 0 && z == 0)。
PointXYZ* NewPoint = new PointXYZ(x, y, z);
Input.push_back(*NewPoint);
这是我的问题:
在将数据发送到GPU之前读取数据的最佳输入结构是什么? (当前读数大约需要120秒)。
我在2d图像中没有正确的点索引(因为我忽略了没有信息的点)。每个点都包含x,y,z值。找到3/6/9最近的邻居的最准确但不是那么先进的算法是什么?通过GPU对该数量的点进行线性比较(强力)效率不高吗?
我当时在看八叉树,但是我不确定在没有适当索引的情况下如何划分点云。
答案 0 :(得分:0)
我刚刚做了一些测试。我使用了具有10'000'000点的有点聚类的3D数据集。实现是用Java实现的,我使用了qthypercube2实现。
我从没使用过GPU,但让我们做一些数学运算: 我假设“蛮力”是指将每个点与每个其他点进行比较? 10 ^ 7点表示10 ^ 14比较操作。每个比较花费10个周期(只有一个数字)意味着10 ^ 15个计算周期。假设GPU允许并行执行1000次操作,这仍然意味着10 ^ 12个周期。如果您的GPU的时钟频率为1GHz(每秒10 ^ 9个操作),则总搜索将为10 ^ 12/10 ^ 9 = 10 ^ 3 = 1000秒。 这没有考虑:将数据加载到GPU中,存储(中间)最近的邻居,对中间结果(如果大于1NN)进行排序,...
当然,GPU和NN搜索实现的细节可能会有所不同,数据集的实际大小可能也会有所不同。所有这些可能会减少或增加这1000秒。 同样对于四叉树,数据集特征(聚类等)可能会发挥重要作用,搜索类型也可能会发挥重要作用(我测试了3个最近的邻居)。同样,我的实现是“通用的”,因为它适用于任何维度。专用的3D实施可能会更快。
我的猜测:在1千万点时,使用四叉树应该比GPU版本更快,并且绝对易于实现。