在cuda中的1个事务中读取每个线程4个字符

在cuda中的1个事务中读取每个线程4个字符,cuda,Cuda,我最近在学习中文大学。我有一个关于内存事务的问题。 我的理解是,在每个事务中,32个连续线程(在同一块中)可以同时访问连续128字节(32个单精度字)的内存,这称为扭曲。 但在本例中,每个线程总是将(4字节)字作为一个完整变量进行访问。所以我的问题是,如果我在全局内存中的数组被定义为字符类型,那么所有32个线程可以访问这段内存,并在同一时间分别读取4个连续字符吗 因此,对于EAX示例,如果我编写代码: __global__ void kernel(char *d_mask) { exte

我最近在学习中文大学。我有一个关于内存事务的问题。 我的理解是,在每个事务中,32个连续线程(在同一块中)可以同时访问连续128字节(32个单精度字)的内存,这称为扭曲。 但在本例中,每个线程总是将(4字节)字作为一个完整变量进行访问。所以我的问题是,如果我在全局内存中的数组被定义为字符类型,那么所有32个线程可以访问这段内存,并在同一时间分别读取4个连续字符吗

因此,对于EAX示例,如果我编写代码:

__global__
void kernel(char *d_mask)
{
    extern __shared__ char s_tmp[];
    const unsigned int thId = threadIdx.x;
    const unsigned int elementId = 4 * (threadIdx.x + blockDim.x * blockIdx.x);

    s_tmp[thId_x] = d_mask[elementId];
    s_tmp[1 + thId_x] = d_mask[elementId + 1];
    s_tmp[2 + thId_x] = d_mask[elementId + 2];
    s_tmp[3 + thId_x] = d_mask[elementId + 3];
    __syncthreads();

    /* calculation */
}

那么,每个线程会同时读取4个字节吗?如果没有,我怎么能做到呢?我是否应该使用memcpy之类的API?

为了获得适当有效的读取,有必要将正在读取的字节合并到单个事务中;我们通常不能通过跨多行代码来实现这一点

为了将事物组合成单个事务,有一些向量类型将多个元素组合成单个类型。只要我们使用,我们就可以将
char
无符号char
数组视为数组,例如
uchar4
,它是一种向量类型,将四个字符组合为一个(32位)类型。你可以在cuda头文件
vector\u types.h
vector\u functions.h
中找到更多的好东西

无论如何,我们可以像这样重新编写您的示例,以利用“向量负载”:

\u全局__
无效内核(char*d_掩码)
{
外部共享字符s_tmp[];
常量unsigned int thId=threadIdx.x;
常量unsigned int elementId=threadIdx.x+blockDim.x*blockIdx.x;
uchar4*s_tmp_v=重新解释演员阵容(s_tmp);
uchar4*d_mask_v=重新解释铸造(d_mask);
s_tmp_v[thId]=d_mask_v[elementId];
__同步线程();
/*算计*/
}

为了获得正确有效的读取,有必要将正在读取的字节合并到单个事务中;我们通常不能通过跨多行代码来实现这一点

为了将事物组合成单个事务,有一些向量类型将多个元素组合成单个类型。只要我们使用,我们就可以将
char
无符号char
数组视为数组,例如
uchar4
,它是一种向量类型,将四个字符组合为一个(32位)类型。你可以在cuda头文件
vector\u types.h
vector\u functions.h
中找到更多的好东西

无论如何,我们可以像这样重新编写您的示例,以利用“向量负载”:

\u全局__
无效内核(char*d_掩码)
{
外部共享字符s_tmp[];
常量unsigned int thId=threadIdx.x;
常量unsigned int elementId=threadIdx.x+blockDim.x*blockIdx.x;
uchar4*s_tmp_v=重新解释演员阵容(s_tmp);
uchar4*d_mask_v=重新解释铸造(d_mask);
s_tmp_v[thId]=d_mask_v[elementId];
__同步线程();
/*算计*/
}
__global__
void kernel(char *d_mask)
{
    extern __shared__ char s_tmp[];
    const unsigned int thId = threadIdx.x;
    const unsigned int elementId = threadIdx.x + blockDim.x * blockIdx.x;

    uchar4 *s_tmp_v  = reinterpret_cast<uchar4 *>(s_tmp);
    uchar4 *d_mask_v = reinterpret_cast<uchar4 *>(d_mask);
    s_tmp_v[thId] = d_mask_v[elementId];
    __syncthreads();

    /* calculation */
}