在CUDA和C ++中命名mangling

时间:2015-02-28 13:52:01

标签: c++ cuda nvcc name-mangling pgi

使用来自PGI的main.cpp编译的我的C ++项目pgcpp在一个单独的文件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作为主机代码,而且这个编译器的名称与pgcpp不同吗?

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

1 个答案:

答案 0 :(得分:2)

默认情况下,

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

PGI为编译C ++代码提供了两个稍微不同的工具链。使用pgcpp工具调用一个工具链。此工具链 gnu兼容,并且不一定会产生与gnu兼容的名称修改。使用pgc++工具调用另一个工具链,并将其公布为gnu兼容,并且应该生成与gnu兼容的名称修改。

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

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

PGI users guide的当前版本(例如第xv页)和PGI 2015 release notes中引用了pgcpppgc++之间的差异:

  

PGI 2015特色与表现

     

•PGI C ++编译器

     

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

     

...

     

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

请注意pgc++现在(2015年)被认为是"默认" pgcpp列为"已弃用。"