CUDA 和 C++ 中的名称重整

Name mangling in CUDA and C++

我的 C++ 项目 main.cpp,使用 PGI pgcpp 编译,调用函数 cuda() 在单独的文件 cuda.cu 中包含 CUDA 代码,使用 [=16] 编译=].除非我在函数声明和公共头文件中用 extern "C" 包装 cuda() 函数,否则我会收到链接错误(未定义的引用)。

没有 extern "C"(符号名称不匹配 => 未定义引用):

$ nm main.o | grep -y cuda
U cuda__FPfPiT2iN32
$ nm cuda.o | grep -y cuda
T _Z13cudaPfPiS0_iS0_S0_S0_

使用 extern "C"(符号名称匹配 => 链接正常):

$ nm main.o | grep -y cuda
U cuda
$ nm cuda.o | grep -y cuda
T cuda

我的印象是 nvcc 将主机 C++ 编译器用于主机代码,因此它会像在 C++ 中那样破坏符号名称?那我做错了什么?

编辑:这可能是由于 nvcc 实际上将 GNU 编译器 gcc 用于主机代码,并且该编译器对名称的处理方式与 pgcpp 不同?

EDIT2:我的系统有 pgcpp 14.9、gcc 4.4.7、nvcc/CUDA 6.5

nvcc 默认使用(在 linux 上)主机 gcc/g++ (gnu) 工具链。

PGI 提供了两个略有不同的工具链来编译 C++ 代码。使用 pgcpp 工具调用一个工具链。此工具链 gnu 兼容,并且不一定会产生 gnu 兼容的名称修改。另一个工具链是使用 pgc++ 工具调用的,它被宣传为与 gnu 兼容,并且应该产生与 gnu 兼容的名称修改。

nvcc 和 PGI 工具生成的对象之间的此类链接问题应使用 pgc++ 工具解决。

顺便说一句,使用 CUDA 7 现在可以使用 PGI 编译器 (pgc++) 作为 nvcc 的主机编译器。然而,这不是问题的症结所在,尽管切换到该主机编译器会以类似的方式解决链接问题。

pgcpppgc++ 之间的差异在 PGI users guide (e.g. page xv) and the PGI 2015 release notes 的当前版本中提到:

PGI 2015 Features and Performance

•PGI C++ Compiler

◦PGC++ (pgc++) is now default on Linux and OS X. Features include GNU compatible name mangling and language features supporting g++ versions 4.2-4.8.

...

◦pgc++ is also now supported as an NVCC host compiler on Linux

请注意,pgc++ 现在 (2015) 被视为“默认”,pgcpp 被列为“已弃用”。