0

我正在研究 DNA 片段组装程序。仅 CPU 版本是使用 GCC 以 C 语言构建的,我正在尝试使用 NVCC 构建 GPU 版本。

这是生成文件

all : clean FragmentAssembly.exe

FragmentAssembly.exe : Common.o Fragment.o ILS.o Consensus.o main.o
    nvcc -pg -o FragmentAssembly.exe Common.o Fragment.o ILS.o Consensus.o main.o 

Common.o : Common.cu
    nvcc -pg -o Common.o -c Common.cu

Fragment.o : Fragment.cu
    nvcc -pg -o Fragment.o -c Fragment.cu

ILS.o : ILS.cu
    nvcc -pg -o ILS.o -c ILS.cu

Consensus.o : Consensus.cu
    nvcc -pg -o Consensus.o -c Consensus.cu

main.o : main.cu
    nvcc -pg -o main.o -c main.cu

clean : 
    rm -f *.exe *.o

如图所示,原始.c文件变成了 .cu 文件,nvcc以便正确编译它们。除了main.cu.

ILS.h 包含全局变量的定义p_instanceFragmentsp_instanceLength

问题是在编译 NVCC 时,由于未知原因,我收到以下错误:

Consensus.o:(.bss+0x0): multiple definition of `p_instanceFragments'
ILS.o:(.bss+0x0): first defined here
Consensus.o:(.bss+0x8): multiple definition of `p_instanceLength'
ILS.o:(.bss+0x8): first defined here

没有真正的多重定义,因为使用 GCC 正确构建了相同的代码。看起来好像ILS.h被两次包含在 nvcc 中,分别是ILS.cuConsensus.cu。这也是不可能的,因为我已经用#ifndef .. #define .. #endif语句包装了所有头文件,以避免多次包含和无限包含循环。

也许与makefile命令有关?还是我应该使用 gcc 进行链接?你能告诉我如何处理吗?

问候,

4

1 回答 1

0

讨论后:这里描述发生了什么:

如果您使用 gcc 并且您有两个文件(比如说f1.cf2.c),并且在两个文件中声明:

int myGlobalVariable;

然后会发生以下情况:

  • 编译f1.cf1.o时,目标文件会为myGlobalVariable.
  • 编译f2.cf2.o. 时,目标文件也会为myGlobalVariable.
  • 当您将两个目标文件链接在一起时,链接器将检测到调用了两个变量myGlobalVariable并将这些变量合并在一起。

现在看来nvcc编译器/链接器无法合并这些变量。

问题是,该文件ILS.h声明<some type> p_instanceFragments;. 因为ILS.h包含在两者ILS.cuConsensus.cu,所以你得到这个变量两次,并nvcc在它必须链接应用程序时抱怨。

解决方案是声明extern <some type> p_instanceFragments;inILS.h然后定义<some type> p_instanceFragments;inILS.cu Consensus.cu(不在两者中)。

什么是 C 中的外部变量这个问题有一个相当广泛的答案,详细解释了所有这些。

于 2013-06-13T17:40:50.037 回答