首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >库达内存对齐

库达内存对齐
EN

Stack Overflow用户
提问于 2012-10-08 09:33:38
回答 2查看 17.1K关注 0票数 18

在我的代码中,我使用结构是为了方便将争论传递给函数(我不使用结构数组,而是一般数组的结构)。当我在库达-gdb时,我检查内核中的点,在那里我给出了一个简单结构的值,例如

代码语言:javascript
复制
struct pt{
int i;
int j;
int k;
}

虽然我不是在做复杂的事情,而且很明显,成员们应该有自己的价值观,但我得到……

当询问堆栈的位置0时,堆栈上只有0个元素。

所以我在想,即使它不是一个数组,但在那个时候,内存的对齐可能有问题。因此,我将头文件中的定义更改为

代码语言:javascript
复制
struct __align__(16) pt{
int i;
int j;
int k;
}

但是,当编译器试图编译使用相同定义的主机代码文件时,会出现以下错误:

错误:数字常量错误之前的期望非限定-id:预期‘)’在数字常量错误之前:预期构造函数、析构函数或“;”之前的类型转换

那么,我应该对主机和设备结构有两个不同的定义吗?

此外,我想问一问如何概括协调的逻辑。我不是一个计算机科学家,所以编程指南中的两个例子并不能帮助我了解全局。

例如,下面两个应该如何对齐?或者,一个有6个浮子的结构应该如何对齐?还是四个整数?同样,我没有使用这些数组,但我仍然在内核或_ device _ functions中使用这些结构定义了许多变量。

代码语言:javascript
复制
struct {
    int a;
    int b;
    int c;
    int d;
    float* el;    
} ;

 struct {
    int a;
    int b
    int c
    int d
    float* i;
    float* j;
    float* k;
} ;

谢谢您的任何建议或暗示。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-10-08 10:21:56

在这篇文章中有很多问题。由于CUDA编程指南在解释CUDA中的对齐方面做得很好,我将只解释一些指南中不太明显的内容。

首先,主机编译器给出错误的原因是主机编译器不知道__align(n)__是什么意思,所以它给出了一个语法错误。您需要的是将类似于以下内容的内容放在项目的标题中。

代码语言:javascript
复制
#if defined(__CUDACC__) // NVCC
   #define MY_ALIGN(n) __align__(n)
#elif defined(__GNUC__) // GCC
  #define MY_ALIGN(n) __attribute__((aligned(n)))
#elif defined(_MSC_VER) // MSVC
  #define MY_ALIGN(n) __declspec(align(n))
#else
  #error "Please provide a definition for MY_ALIGN macro for your host compiler!"
#endif

那么,我应该对主机和设备结构有两个不同的定义吗?

不,只要使用MY_ALIGN(n),就像这样

代码语言:javascript
复制
struct MY_ALIGN(16) pt { int i, j, k; }

例如,下面两个应该如何对齐?

首先,__align(n)__ (或任何一种主机编译器风格)强制要求结构的内存从内存中的一个地址开始,该地址是n字节的倍数。如果结构的大小不是n的倍数,那么将在这些结构的数组中插入填充,以确保每个结构正确地对齐。要为n选择适当的值,您需要最小化所需的填充量。正如编程指南中所解释的那样,硬件要求每个线程读取与1、2、4、8或16字节对齐的单词。所以..。

代码语言:javascript
复制
struct MY_ALIGN(16) {
  int a;
  int b;
  int c;
  int d;
  float* el;    
};

在这种情况下,假设我们选择16字节对齐。在32位机器上,指针需要4个字节,所以struct需要20个字节.16字节对齐将浪费每个结构的16 * (ceil(20/16) - 1) = 12字节。在64位机器上,由于8字节指针,每个结构只浪费8个字节.我们可以用MY_ALIGN(8)来减少浪费。交换条件是硬件必须使用3 8字节的负载,而不是2 16字节的负载才能从内存中加载结构。如果你没有受到负载的阻碍,这可能是一个值得的权衡。请注意,对于此结构,您不希望对齐小于4个字节。

代码语言:javascript
复制
struct MY_ALIGN(16) {
  int a;
  int b
  int c
  int d
  float* i;
  float* j;
  float* k;
};

在这种情况下,使用16字节对齐,32位机器上每个结构只浪费4个字节,在64位机器上浪费8个字节。它需要两个16字节的加载(或64位计算机上的3个)。如果我们对齐8字节,我们可以完全消除4字节对齐(64位机器上的8字节)的浪费,但这会导致过多的负载。再一次权衡一下。

或者,一个有6个浮子的结构应该如何对齐?

同样,权衡:要么每个结构浪费8个字节,要么每个结构需要两个加载。

还是四个整数?

这里没有交易。MY_ALIGN(16)

同样,我没有使用这些数组,但我仍然在内核或_ device _ functions中使用这些结构定义了许多变量。

嗯,如果您没有使用这些数组,那么您可能根本不需要对齐。但你是怎么分配给他们的?正如您可能看到的那样,所有这些浪费都很重要--这是支持数组结构而不是数组结构的另一个很好的理由。

票数 31
EN

Stack Overflow用户

发布于 2016-03-21 18:50:45

现在,您应该使用由GCC (包括与当前数据自动化系统兼容的版本)支持的C++11 说明符、由MSVC 因为提供的2015年版本,以及由nvcc支持的IIANM。这样你就不用求助于宏了。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12778949

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档