在我的代码中,我使用结构以便于将争论传递给函数(我不使用结构数组,而是使用数组结构).当我在cuda-gdb中时,我会检查内核中的一个点,我将值赋给一个简单的结构
struct pt{
int i;
int j;
int k;
}
Run Code Online (Sandbox Code Playgroud)
即使我没有做一些复杂的事情,很明显成员应该有指定的价值,我得到...
当被问到堆栈的位置0时,堆栈上只有0个元素.
所以我在想,即使它不是一个数组,也许在这一点上存储器的对齐存在问题.所以我将头文件中的定义更改为
struct __align__(16) pt{
int i;
int j;
int k;
}
Run Code Online (Sandbox Code Playgroud)
但是,当编译器尝试编译使用相同定义的主机代码文件时,会出现以下错误:
错误:数字常量错误之前的预期unqualified-id:数字常量错误之前的预期')':';'之前的预期构造函数,析构函数或类型转换 代币
那么,我应该对主机和设备结构有两种不同的定义吗?
此外,我想问一下如何概括对齐的逻辑.我不是计算机科学家,因此编程指南中的两个例子并没有帮助我了解全局.
例如,如何对齐以下两个?或者,如何将6个浮子的结构对齐?还是4个整数?再次,我没有使用那些数组,但我仍然在内核或_ device _函数中使用这些结构定义了很多变量.
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;
} ;
Run Code Online (Sandbox Code Playgroud)
提前感谢您的任何建议或提示
har*_*ism 30
这篇文章中有很多问题.由于CUDA编程指南在解释CUDA中的对齐方面做得非常好,我将只解释一些在指南中不明显的内容.
首先,主机编译器给你错误的原因是主机编译器不知道什么__align(n)__意思,所以它给出了语法错误.您需要的是在项目的标题中添加以下内容.
#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
Run Code Online (Sandbox Code Playgroud)
那么,我应该对主机和设备结构有两种不同的定义吗?
不,只是MY_ALIGN(n)像这样使用
struct MY_ALIGN(16) pt { int i, j, k; }
Run Code Online (Sandbox Code Playgroud)
例如,如何对齐以下两个?
首先,__align(n)__(或任何主机编译器风格)强制结构的内存开始于内存中多个n字节的地址.如果struct的大小不是double的倍数n,那么在这些结构的数组中,将插入填充以确保每个结构正确对齐.要为其选择适当的值n,您希望最小化所需的填充量.如编程指南中所述,硬件要求每个线程读取对齐到1,2,4,8或16字节的字.所以...
struct MY_ALIGN(16) {
int a;
int b;
int c;
int d;
float* el;
};
Run Code Online (Sandbox Code Playgroud)
在这种情况下,假设我们选择16字节对齐.在32位机器上,指针占用4个字节,因此struct占用20个字节.16字节对齐将浪费16 * (ceil(20/16) - 1) = 12每个结构的字节.在64位机器上,由于8字节指针,每个结构只会浪费8个字节.我们可以通过使用MY_ALIGN(8)来减少浪费.权衡将是硬件必须使用3个8字节加载而不是2个16字节加载来从内存加载结构.如果你没有受到负载的瓶颈,这可能是值得的权衡.请注意,您不希望为此结构对齐小于4个字节.
struct MY_ALIGN(16) {
int a;
int b
int c
int d
float* i;
float* j;
float* k;
};
Run Code Online (Sandbox Code Playgroud)
在这种情况下,对于16字节对齐,您在32位计算机上每个结构只浪费4个字节,在64位计算机上浪费8个字节.它需要两个16字节的负载(或64位机器上的3个).如果我们对齐到8个字节,我们可以通过4字节对齐(64位机器上的8字节)完全消除浪费,但这会导致过多的负载.再次,权衡.
或者,如何将6个浮子的结构对齐?
再次,权衡:要么每个结构浪费8个字节,要么每个结构需要两个负载.
还是4个整数?
这里没有权衡.MY_ALIGN(16).
再次,我没有使用那些数组,但我仍然在内核或_ device _函数中使用这些结构定义了很多变量.
嗯,如果你没有使用这些数组,那么你可能根本不需要对齐.但是你如何分配给他们?正如您可能已经看到的那样,所有这些浪费都是值得担心的重要因素 - 这是在结构数组上支持数组结构的另一个好理由.