【问题标题】:Finding nearest neighbours in 3d point cloud, GPU在 3d 点云,GPU 中寻找最近的邻居
【发布时间】:2018-07-07 09:55:59
【问题描述】:

我想通过 GPU 计算点云中每个点的最近邻。 我的数据集如下所示:

<number of points in column>
<number of columns>

x   y   z
x   y   z
z   y   z
... ... ... 

有将近 20^6 个点。
我正在使用vector&lt;PointXYZ&gt; 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);

这是我的问题:

  1. 在将数据发送到 GPU 之前读取数据的最佳输入结构是什么? (当前读数大约需要 120 秒)。

  2. 我在 2d 图像中没有正确的点索引(因为我忽略了没有信息的点)。每个点都包含 x,y,z 值。找到 3/6/9 最近邻的最准确但不那么先进的算法是什么?通过 GPU 对这些点进行线性比较(蛮力)是否效率不高?

我正在查看八叉树,但我不确定在没有适当索引的情况下如何划分点云。

【问题讨论】:

  • 你可以reserve(...)你的向量来获取它将包含的元素的最终数量,只分配一次。这将加快速度。此外,如果您想进一步加快速度,请为您的数据集使用二进制数据格式,它会更小
  • 你确定20^6分吗?这大约是 6400 万,对吗?

标签: c++ multidimensional-array gpu gpgpu nearest-neighbor


【解决方案1】:

我刚刚做了一些测试。我使用了一个包含 10'000'000 点的有点聚集的 3D 数据集。实现是用 Java 编写的,我使用了我的 qthypercube2 实现。

  1. 对于我的测试,我经常将数据作为一个大的 float[] BLOB 存储在数据库中。将 10'000'000 个点加载到内存中大约需要 0.5 秒。
  2. 将数据加载到四叉树中(我使用自己的特殊实现)大约需要 4 秒。
  3. 执行 1'000'000 次 3-NN 搜索大约需要 20 秒,对于 10'000'000 次 3-N 搜索大约需要 200 秒或 3.3 分钟。

我从未使用过 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 实现可能会更快。

我的猜测:在 10M 点上,使用四叉树应该比 GPU 版本更快,并且肯定更容易实现。

【讨论】:

    猜你喜欢
    • 2019-11-28
    • 2011-06-24
    • 2021-04-29
    • 2019-06-04
    • 2020-11-05
    • 1970-01-01
    • 2018-06-26
    • 2011-03-12
    • 1970-01-01
    相关资源
    最近更新 更多