Cuda 为什么在获取内存时,由4个无符号字符组成的静态声明数组生成ld.global.u8?

Cuda 为什么在获取内存时,由4个无符号字符组成的静态声明数组生成ld.global.u8?,cuda,gpgpu,nvcc,Cuda,Gpgpu,Nvcc,我正在使用CUDA 5.5,我发现编译器的行为有点奇怪,如果我试图处理一个只有4个无符号字符的结构,它会触发4次u8加载。相反,如果我使用union并加载uchar4,它将生成所需的nc.v4.u8加载 此代码生成 ld.global.u8%rs5,[%r32] const int wu = 4; struct data { uchar_t v[wu]; CUDA_CALLABLE_MEMBER

我正在使用CUDA 5.5,我发现编译器的行为有点奇怪,如果我试图处理一个只有4个无符号字符的结构,它会触发4次u8加载。相反,如果我使用union并加载uchar4,它将生成所需的nc.v4.u8加载

此代码生成 ld.global.u8%rs5,[%r32]

        const int wu = 4;
        struct data {
            uchar_t v[wu];           
            CUDA_CALLABLE_MEMBER uchar_t &operator[] (int i) {
                return v[i];
            }
        } fetch[rows];

        for (int i = 0; i < rows; i++) {
            fetch[i] = *((data*)&src[offsetSrc + i*strideSrc]);
        }
       const int wu = 4;
       struct data {
            union {
                uchar_t v[wu];
                uchar4 v4;
            };
            CUDA_CALLABLE_MEMBER uchar_t &operator[] (int i) {
                return v[i];
            }
        } fetch[rows];

        for (int i = 0; i < rows; i++) {
            fetch[i].v4 = *((uchar4*)&src[offsetSrc + i*strideSrc]);
        }
const int wu=4;
结构数据{
乌恰尔托夫[吴];
CUDA_可呼叫成员uchar_t&operator[](int i){
返回v[i];
}
}取[行];
对于(int i=0;i
因此,我必须通过建立一个联盟来解决这一问题,以生产所需的: ld.global.nc.v4.u8{%rs49、%rs50、%rs51、%rs52}、[%r37]

        const int wu = 4;
        struct data {
            uchar_t v[wu];           
            CUDA_CALLABLE_MEMBER uchar_t &operator[] (int i) {
                return v[i];
            }
        } fetch[rows];

        for (int i = 0; i < rows; i++) {
            fetch[i] = *((data*)&src[offsetSrc + i*strideSrc]);
        }
       const int wu = 4;
       struct data {
            union {
                uchar_t v[wu];
                uchar4 v4;
            };
            CUDA_CALLABLE_MEMBER uchar_t &operator[] (int i) {
                return v[i];
            }
        } fetch[rows];

        for (int i = 0; i < rows; i++) {
            fetch[i].v4 = *((uchar4*)&src[offsetSrc + i*strideSrc]);
        }
const int wu=4;
结构数据{
联合{
乌恰尔托夫[吴];
uchar4 v4;
};
CUDA_可呼叫成员uchar_t&operator[](int i){
返回v[i];
}
}取[行];
对于(int i=0;i
GPU要求所有数据自然对齐(即16位数据为16位对齐,32位数据为32位对齐,64位数据为64位对齐,等等)。uchar4是由四个无符号字符组成的结构,通过使用对齐属性进行32位对齐。因此,它可以通过单个32位访问加载。另一方面,由四个无符号字符组成的数组不能保证32位对齐,因此不能用单个32位加载加载。根据任何组成部分所需的最严格校准,对接头进行校准


用户定义的数据类型可以与
\uuuuu align\uuuu
属性对齐,该属性在中描述。GPU要求所有数据自然对齐(即16位数据为16位对齐,32位数据为32位对齐,64位数据为64位对齐,等等)。uchar4是由四个无符号字符组成的结构,通过使用对齐属性进行32位对齐。因此,它可以通过单个32位访问加载。另一方面,由四个无符号字符组成的数组不能保证32位对齐,因此不能用单个32位加载加载。根据任何组成部分所需的最严格校准,对接头进行校准


用户定义的数据类型可以与
\uuuuuu align\uuuuu
属性对齐,这在中有描述,问题是什么?问题是我不理解为什么编译器在完全相同的结构中生成单个加载。。。我认为编译器足够聪明,知道我的结构是对齐的(或者可以对齐)。但是我看到问题来自间接(data*)和(uchar4*)。如果指针“src”是一个指向4字节对齐类型/结构(例如int*)的指针,那么对于原始结构,编译器应该生成一个32b加载还是四个8b加载?问题在标题中。这是一个很好的问题+1问题是什么?问题是我不明白为什么编译器在一个完全相同的结构中产生一个加载。。。我认为编译器足够聪明,知道我的结构是对齐的(或者可以对齐)。但是我看到问题来自间接(data*)和(uchar4*)。如果指针“src”是一个指向4字节对齐类型/结构(例如int*)的指针,那么对于原始结构,编译器应该生成一个32b加载还是四个8b加载?问题在标题中。这是一个很好的问题+1.