Mik*_*ail 6 c c++ gcc cuda nvcc
我正在尝试将CUDA添加到90年代末期编写的现有单线程C程序中.
为此,我需要混合两种语言,C和C++(nvcc是一个c ++编译器).
问题是C++编译器将结构看作某个大小,而C编译看到的结构与稍微不同的大小相同.那很糟.我真的很困惑,因为我找不到4字节差异的原因.
/usr/lib/gcc/i586-suse-linux/4.3/../../../../i586-suse-linux/bin/ld: Warning: size of symbol `tree' changed from 324 in /tmp/ccvx8fpJ.o to 328 in gpu.o
Run Code Online (Sandbox Code Playgroud)
我的C++看起来像
#include <stdio.h>
#include <stdlib.h>
#include "assert.h"
extern "C"
{
#include "structInfo.h" //contains the structure declaration
}
...
Run Code Online (Sandbox Code Playgroud)
和我的C文件看起来像
#include "structInfo.h"
...
Run Code Online (Sandbox Code Playgroud)
与structInfo.h看起来像
struct TB {
int nbranch, nnode, root, branches[NBRANCH][2];
double lnL;
} tree;
...
Run Code Online (Sandbox Code Playgroud)
我的make文件看起来像
PRGS = prog
CC = cc
CFLAGS=-std=gnu99 -m32
CuCC = nvcc
CuFlags =-arch=sm_20
LIBS = -lm -L/usr/local/cuda-5.0/lib -lcuda -lcudart
all : $(PRGS)
prog:
$(CC) $(CFLAGS) prog.c gpu.o $(LIBS) -o prog
gpu.o:
$(CuCC) $(CuFlags) -c gpu.cu
Run Code Online (Sandbox Code Playgroud)
有些人问我为什么不使用不同的主机编译选项.我认为主机编译选项自2发布以来已被弃用?也一直没有出现做什么它说,它会做.
nvcc warning : option 'host-compilation' has been deprecated and is ignored
Run Code Online (Sandbox Code Playgroud)
nju*_*ffa 16
GPU需要对所有数据进行自然对齐,例如,4字节的int需要与4字节边界对齐,8字节的double或long long需要具有8字节的对齐.CUDA也对主机代码强制执行此操作,以确保结构在代码的主机和设备部分之间尽可能兼容.另一方面,x86 CPU通常不需要数据自然对齐(尽管性能损失可能是由于缺少对齐).
在这种情况下,CUDA需要将结构的double组件与8字节边界对齐.由于奇数个int组件在double之前,因此需要填充.切换组件的顺序,即将双组件放在第一位,没有用,因为在这种结构的数组中,每个结构必须是8字节对齐的,因此结构的大小必须是8字节的倍数才能实现,这也需要填充.
要强制gcc以与CUDA相同的方式对齐双打,请传递标记-malign-double.
看起来像2个编译器应用的不同填充:一个使用4字节对齐,另一个使用至少8字节对齐.您应该能够通过编译器特定的#pragma指令强制执行所需的对齐(请查看有关特定的编译器文档#pragma).