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
的主机编译器。然而,这不是问题的症结所在,尽管切换到该主机编译器会以类似的方式解决链接问题。
pgcpp
和 pgc++
之间的差异在 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
被列为“已弃用”。
我的 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
的主机编译器。然而,这不是问题的症结所在,尽管切换到该主机编译器会以类似的方式解决链接问题。
pgcpp
和 pgc++
之间的差异在 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
被列为“已弃用”。