2

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

没有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主机代码,并且该编译器对名称的处理方式与 GNU 编译器不同pgcpp吗?

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

4

1 回答 1

2

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

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

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

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

当前版本的PGI 用户指南(例如第 xv 页)和PGI 2015 发行说明中提到了两者之间pgcpp的差异:pgc++

PGI 2015 功能和性能

•PGI C++ 编译器

◦PGC++ (pgc++) 现在是 Linux 和 OS X 的默认设置。功能包括 GNU 兼容的名称修改和支持 g++ 4.2-4.8 版本的语言功能。

...

◦现在也支持 pgc++ 作为 Linux 上的 NVCC 主机编译器

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

于 2015-03-01T20:35:03.923 回答