c++ - 为什么 gcc 和 NVCC (g++) 看到两种不同的结构大小?

标签 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

我的 C++ 看起来像

#include <stdio.h>
#include <stdlib.h>
#include "assert.h"
extern "C"
{
#include "structInfo.h" //contains the structure declaration
}
...

我的 C 文件看起来像

#include "structInfo.h"
...

structInfo.h 看起来像

struct TB {
   int  nbranch, nnode, root, branches[NBRANCH][2];
         double lnL;
}  tree;
...

我的 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

有人问我为什么不使用不同的主机编译选项。我认为主机编译选项自 2 发布前已被弃用?还有 it never appeared to do what it said it would do .

nvcc warning : option 'host-compilation' has been deprecated and is ignored

最佳答案

GPU 要求所有数据自然对齐,例如一个 4 字节的 int 需要对齐到 4 字节的边界,一个 8 字节的 double 或 long long 需要有 8 字节对齐。 CUDA 也对主机代码强制执行此操作,以确保结构在代码的主机部分和设备部分之间尽可能兼容。另一方面,x86 CPU 通常不要求数据自然对齐(尽管缺乏对齐可能会导致性能下降)。

在这种情况下,CUDA 需要将结构的 double 组件与 8 字节边界对齐。由于奇数个 int 组件位于 double 之前,因此需要填充。切换组件的顺序,即将 double 组件放在第一位,无济于事,因为在这样的结构数组中,每个结构都必须是 8 字节对齐的,因此结构的大小必须是 8 字节的倍数才能实现,这也需要填充。

要强制 gcc 以与 CUDA 相同的方式对齐 double ,请传递标志 -malign-double

关于c++ - 为什么 gcc 和 NVCC (g++) 看到两种不同的结构大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13782480/

相关文章:

c++ - 如何将 int 转换为 LPARAM c/c++?

c++ - 在父类中声明并在子类中定义

c - 抛出异常 : read access violation. 无法打印头文件中的信息

gcc - 架构arm64的 undefined symbol : while using vs code to run c/c++

android - 编译为在 Android x86 架构上运行的 OpenSSL

c++ - Raspberry Pi通过PiFM产生音调

c++ - 将函数作为参数传递给模板返回值

c - 如何选择 STDIN_FILENO 忽略信号?

ios - 为什么条件运算符为第一条语句提供所需的结果而不是第二条语句?

c - 在 C 中分配 128 位整数