C标题重复符号问题

the*_*lad 2 c c++ cuda header-files duplicate-symbol

这是我第一次处理一个比简单的write-single-source-file-and-compile例程稍微复杂一点的CUDA项目.正如所料,我面临着C标题的一些问题,即重复的符号.

根据链接器,在多个.cu文件中包含以下头文件会产生冲突:

env_vars.h

#ifndef ENV_VARS_H_
#define ENV_VARS_H_

/*** GLOBAL VARIABLES ***/
unsigned int h_n_osc;
__device__ unsigned int d_n_osc;

/*** CONSTANTS ***/
const double OMEGA_0 = 6.447421494058077e+09;

/* other constants defined in the middle */

#endif
Run Code Online (Sandbox Code Playgroud)

multigpu.cu

#include "env_vars.h"
/* assigns h_n_osc */
Run Code Online (Sandbox Code Playgroud)

adm_matrix.cu

#include "env_vars.h"
/* uses h_n_osc */
Run Code Online (Sandbox Code Playgroud)

在Nsight Eclipse Edition中构建项目会导致链接器抱怨h_n_osc变量被定义两次:

duplicate symbol _h_n_osc in:
    ./adm_matrix.o
    ./multigpu.o
ld: 1 duplicate symbol for architecture x86_64
Run Code Online (Sandbox Code Playgroud)

通过互联网搜索,我意识到将h_n_osc变量的声明移动到multigpu.cu并将其重新声明为extern变量adm_matrix.cu(以及我以后可能需要它的任何地方)解决了问题,事实上它确实存在.

问题解决了,但我想深入研究一下:

  1. 链接器为什么不抱怨d_n_osc变量呢?为什么常数(例如OMEGA_0)同样不是问题?
  2. 这是否意味着不可能将全局变量放在头文件中?
  3. 令我最困惑的是,互联网上的许多来源都指出,只有当头文件包含变量的定义时才会发生重复的符号错误,而其简单的声明不应该构成问题.我很难相信这一点的原因是即使我的标题只包含一个声明,我也面临着这个问题!我错过了什么吗?

伙计们,请提前感谢您的耐心等待!

Cli*_*ord 9

头文件通常应该包含声明性代码.h_n_osc应该在这里声明,没有定义.

extern unsigned int h_n_osc;
Run Code Online (Sandbox Code Playgroud)

在您的至少一个模块中,或者您自己的新模块中,您将需要一个定义; 例如:

env_vars.cu

#include "env_vars.h"
unsigned int h_n_osc;
Run Code Online (Sandbox Code Playgroud)

然后链接那个.或者,您当然可以将定义放在现有模块multigpu.cu或adm_matrix.cu中.

我不确定CUDA__device__扩展的语义,虽然它可能链接,但它不一定正确; 您最终可能会引用每个模块引用设备变量的单独副本 ; 也许有必要对此进行限定extern. 这个问题似乎可以解决这个问题.

  • 正确的,`__ device__`(和`__constant__`)变量[有文件/翻译单元范围](http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#memory-declarations). (2认同)