У меня есть основной вопрос, связанный с двумерным доступом к потоку. Я хочу, чтобы скопировать несмежных данных в непрерывный буфер и использование Cuda memcopy можно проиллюстрировать следующим образом:Правильное использование общей памяти CUDA для двумерного несмежного доступа к данным
void pack_cuda(float *dstbuf, IOV *srciov, int num_iov)
{
int i;
float *ptr;
ptr = buf;
for (i = 0; i < num_iov; i++) {
cudaMemcpy(ptr, srciov[i].bufaddr, srciov[i].len, cudaMemcpyDefault);
ptr = (char *)ptr + srciov[i].len;
}
}
* srciov хранит адрес начала памяти и длину каждого несмежных данных в массиве состав.
* dstbuf будет хранить упакованные смежные данные после завершения функции.
Теперь я хочу реализовать его с использованием ядер CUDA.
__global__ void pack_cuda(float *dstbuf, IOV *srciov, int num_iov)
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;
int k;
extern __shared__ size_t tmpdbuflen[16*3]; //suppose num_iov is 16
if (j == 0){
if (i < 16){
tmpdbuflen[i] = (srciov[i].len); //store length to calculate presum
tmpdbuflen[i+16] = tmpdbuflen[i]; //store length
tmpdbuflen[i+32] = ((srciov+i)->bufaddr) - (srciov->bufaddr); //store addr difference
}
__syncthreads();
for (k = 0; k < i; k++)
tmpdbuflen[i] += srciov[k].len;
}
__syncthreads();
if (i < 16 && j < srciov[i].len){ //wondering whether this is correct use
dst[tmpdbuflen[i] + j] = *(src + tmpdbuflen[i+32] + j);
}
__syncthreads();
}
Kernel призывание часть:
dim3 dimblock(16, 16); //the length of each non-contiguous data is less than 16
dim3 dimgrid(1,1);
const unsigned int shm_size = sizeof(size_t) * 16 * 3;
pack_cuda<<<dimgrid, dimblock, shm_size, 0>>>(dstbuf, srciov, num_iov);
cudaDeviceSynchronize();
Тем не менее, кажется, что я не могу упаковать все необходимые ДАННЫЕ Into Dst буфера. Иногда только j = 0 и 1 (с соответствующими различными i) получают упакованные. Я думаю, что основной проблемой является использование разделяемой памяти. Я использую только потоки столбцов 0 (threadIdx.y == 0) для копирования информации в общую память. Тогда все потоки (без ограничений на threadIdx.y) будут получать доступ и читать информацию в общей памяти. Как изменить код, разрешающий такой дизайн?
Буду признателен, если кто-нибудь сможет выяснить мои проблемы.
Спасибо.