【问题标题】:Name mangling in CUDA and C++CUDA 和 C++ 中的名称修改
【发布时间】:2015-03-02 07:57:40
【问题描述】:

我的 C++ 项目 main.cpp,使用来自 PGI 的 pgcpp 编译,调用了一个函数 cuda(),该函数在单独的文件 cuda.cu 中包含 CUDA 代码,使用 nvcc 编译。除非我在函数声明和公共头文件中用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 在 CUDA 6.5 及之前版本将使用主机 gnu 编译器。 PGI 工具同时具有 PGI“本机”工具链和 PGI gnu 兼容工具链。您可以切换到与 PGI gnu 兼容的工具链(即使用 pgc++ 而不是 pgcpp),或者您可以切换到可以使用 PGI 工具链作为主机编译器的 CUDA 7。您可能想研究PGI documentation
  • 确实这是我的第一反应。 PGI 用户指南没有指出pgc++pgcpp 之间的任何区别。在使用pgc++ 而不是pgcpp 编译纯C++ 代码时,符号名称确实被同样地损坏了。谢谢!
  • 关于此声明:“PGI 用户指南并未指出 pgc++ 和 pgcpp 之间有任何区别”,请尝试查看 PGI user guide 的页面 xv
  • 你是对的。我收到了 2014 版的用户指南。

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


【解决方案1】:

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(例如第 xv 页)和 PGI 2015 release notes 中有所提及:

PGI 2015 功能和性能

•PGI C++ 编译器

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

...

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

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

【讨论】:

    猜你喜欢
    • 2012-11-03
    • 2011-06-07
    • 2011-08-23
    • 2017-11-28
    • 2017-05-22
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    相关资源
    最近更新 更多