比较PCL使用CPU和Nvidia GPU计算效率问题

前言

前篇文章提到,对比PCL使用CPU和Nvidia GPU进行欧式聚类发现,尴尬发现使用CPU的计算效率反而更高。

本篇文章探讨一下原因。

正文

观察代码可以发现,代码中使用CPU欧式聚类的搜索方法选用的是kdtree,使用GPU欧式聚类的搜索方法选用的是octree。感觉有可能是这里的原因导致CPU计算效率更高。于是尝试将CPU的搜索方法也改为octree。

但是编译确保错了,细看官方文档发现

image

image

pcl::search::octree的构造方法中有一个resolution的参数,而在pcl::gpu::octree的构造方法中并没有提供带有resolution参数的构造方法。

尴尬。这样一来就没有保证cpu和gpu计算时同时使用octree。

于是我转头去实现法线估计的cpu和gpu比较。 发现还是同样的问题:同样的方法,其参数在CPU和GPU上的实现不能保持一致。

image

image

在法线估计的参数上,我设置radius=0.03f, max_results=1000

得到结果使用gpu消耗的时间<<cpu消耗的时间,但是我对比了两者结果,发现计算结果的法线向量完全不一样。

如果参数不一样、结果不一样,那么即使计算效率gpu更高,也不能说明什么问题。

后来又发现了在pcl/gpu之外,还有一个pcl/cuda,这下面有一个voxelgrid,结果代码中说does not work…

image

总结一下前述:

  1. 对于欧式聚类,修改参数resolution不会导致结果发生改变;
  2. 对于欧式聚类,gpu和cpu计算结果一致;
  3. 对于欧式聚类,cpu计算效率略高于gpu;
  4. 对于法线估计,修改参数会导致计算结果改变;
  5. 对于欧式聚类,gpu和cpu计算结果不一致;
  6. 对于欧式聚类,cpu计算效率远低于GPU;
  7. 无论是欧式聚类还是法线估计,cpu和gpu提供的接口都有差异,以至于找不到完全一致的参数进行比较。
  8. 除pcl/gpu外,还有pcl/cuda,但是也没什么用。

后来我找到了Nvidia官方提供的PCL cpu和gpu计算比较代码:

https://github.com/NVIDIA-AI-IOT/cuPCL/tree/main

其中提供了聚类、滤波、ICP、NDT、Octree和segmentation的演示代码

image

clone和自己硬件环境对应的代码分支

根据官方的说明,配置好依赖环境,直接进到子目录下make,就可以。但是我尝试死活编译不通。

WX20240624-175840@2x

检查PCL各项环境配置的都没问题,于是创建CMakeLists,通过cmake生成makefile,再make。成功了…

最后编译执行了cuFilter,得到结果如下:

GPU has cuda devices: 1
----device id: 0 info----
GPU : Orin
Capbility: 8.7
Global memory: 15420MB
Const memory: 64KB
SM in a block: 48KB
warp size: 32
threads in a block: 1024
block dim: (1024,1024,64)
grid dim: (2147483647,65535,65535)


------------checking CUDA ----------------
CUDA Loaded 119978 data points from PCD file with the following fields: x y z

------------checking CUDA PassThrough ----------------
CUDA PassThrough by Time: 0.999257 ms.
CUDA PassThrough before filtering: 119978
CUDA PassThrough after filtering: 5110

------------checking CUDA VoxelGrid----------------
CUDA VoxelGrid by Time: 6.46314 ms.
CUDA VoxelGrid before filtering: 119978
CUDA VoxelGrid after filtering: 3440


------------checking PCL ----------------
PCL(CPU) Loaded 119978 data points from PCD file with the following fields: x y z

------------checking PCL(CPU) PassThrough ----------------
PCL(CPU) PassThrough by Time: 3.08542 ms.
PointCloud before filtering: 119978 data points (x y z).
PointCloud after filtering: 5110 data points (x y z).

------------checking PCL VoxelGrid----------------
PCL VoxelGrid by Time: 11.5708 ms.
PointCloud before filtering: 119978 data points (x y z).
PointCloud after filtering: 3440 data points (x y z).

目前该项目源码尚未开源,但是从结果和部分调用的代码来看,参数一致、结果一致,🈶可比较性。

测试结果可以发现使用CUDA可以加速PCL对点云的滤波计算。

补充CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project(cupcl)

set(CMAKE_CXX_STANDARD 17)

# 将资源文件复制到build目录中
# configure_file(${CMAKE_SOURCE_DIR}/cuFilter/lib ${CMAKE_BINARY_DIR}/ COPYONLY)
# configure_file(${CMAKE_SOURCE_DIR}/table_scene_lms400.pcd ${CMAKE_BINARY_DIR}/table_scene_lms400.pcd COPYONLY)


find_package(PCL 1.14 REQUIRED)
find_package(CUDA REQUIRED)

message(STATUS "PCL INCLUDE DIRS : ${PCL_INCLUDE_DIRS}")

include_directories(
${PCL_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/cuFilter/lib
)
link_directories(
${PCL_LIBRARY_DIRS}
${CMAKE_SOURCE_DIR}/cuFilter/lib
)
add_definitions(${PCL_DEFINITIONS})
add_executable(cupcl
# seg1.cpp
cuFilter/main.cpp
)
target_link_libraries(cupcl ${PCL_LIBRARIES} cudafilter ${CUDA_LIBRARIES})
文章作者: Met Guo
文章链接: https://guoyujian.github.io/2024/06/20/%E6%AF%94%E8%BE%83PCL%E4%BD%BF%E7%94%A8CPU%E5%92%8CNvidia-GPU%E8%AE%A1%E7%AE%97%E6%95%88%E7%8E%87%E9%97%AE%E9%A2%98/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Gmet's Blog