C 库达;使用设备内存共享

C 库达;使用设备内存共享,c,memory-management,cuda,C,Memory Management,Cuda,块中的每个线程可以有不同的结果集(和大小)。目前,我正在分配固定大小的设备内存;按线程思考 也就是说,对于XX个线程,我必须分配XX*max\u result\u count*data\u structure*sizeof(int),我的数据包含整数。每个线程通过计算int i=blockDim.x*blockIdx.x+threadIdx.x来访问其内存块(偏移量);对于整数数组,将其与max_result_count*data_结构相乘 在现实世界中,这意味着设备内存的巨大浪费,因为有些集接

块中的每个线程可以有不同的结果集(和大小)。目前,我正在分配固定大小的设备内存;按线程思考

也就是说,对于XX个线程,我必须分配XX*max\u result\u count*data\u structure*sizeof(int),我的数据包含整数。每个线程通过计算int i=blockDim.x*blockIdx.x+threadIdx.x来访问其内存块(偏移量);对于整数数组,将其与max_result_count*data_结构相乘

在现实世界中,这意味着设备内存的巨大浪费,因为有些集接近于0,而有些则不接近。例如,我必须分配低于2GB的设备内存才能存储相当于300MB的结果

关于如何重做这个有什么想法吗

例如,每个线程锁定互斥锁,增加实际res_计数,将数据写入共享内存块,解锁互斥锁


[问题解决了,谢谢,伙计们!]

重写内核并调用函数来计算部分所需的点(显然,您必须更改每次启动的块数等)

int offset=0;
for(int i=0;i

内核中
保留
inti=blockDim.x*blockIdx.x+threadIdx.x
作为全局内存访问的索引,而
i+offset
作为数据位置的id。

您已经在问题中暗示了一种可能的方法:

#define DSIZE (100*1048576)

__device__ unsigned int buffer_index = 0;
__device__ int *buffer_data;
在主机代码中:

int *buffer_data_temp;
cudaMalloc(&buffer_data_temp, sizeof(int)*DSIZE); 
cudaMemcpyToSymbol(buffer_data, &buffer_data_temp, sizeof(int *));
在线程代码中:

unsigned int my_buffer_offset = atomicAdd(&buffer_index, size_of_my_thread_data);
assert((my_buffer_offset+size_of_my_thread_data) < DSIZE);
memcpy(buffer_data+my_buffer_offset, my_thread_data, size_of_my_thread_data*sizeof(int));

有趣的是,我在使用cudaMemcpyFromSymbol()时遇到问题。如果我不能让它工作,我会在这里哭。你不必使用基于设备符号的指针来指向缓冲区数据。您可以使用一个普通的
cudamaloc
创建的
buffer\u data
区域,并将该区域的开头作为参数传递给内核。我正在尝试使用您的代码。编译器说,不能使用断言,不能在设备/全局函数中使用主机函数。您是否可以添加使本地结果计数器递增的代码?因为在我的代码中,局部递增的正数之和不同于(缓冲区\索引/大小\我的\线程\数据)。希望你明白我的意思。对不起,我不明白你的意思。断言不是必需的,它只是一个安全检查。您得到断言错误是因为它仅在cc2.0及更高版本的设备中受支持。简单地说,
buffer\u index/size\u of_my\u thread\u data
与累加的、局部的、线程递增的变量不同-我在
update\u buffer
中有一个循环,如果成功,我会递增局部整数(当我必须memcopy数据结构时),在主循环之后,我将这些变量的数组(每个线程一个)复制到主机内存和主机代码中,添加它们以查看成功迭代的总数。
total number
不同于
buffer\u index/size\u of_my\u thread\u data
unsigned int my_buffer_offset = atomicAdd(&buffer_index, size_of_my_thread_data);
assert((my_buffer_offset+size_of_my_thread_data) < DSIZE);
memcpy(buffer_data+my_buffer_offset, my_thread_data, size_of_my_thread_data*sizeof(int));
#include <stdio.h>
#include <assert.h>
#define DSIZE (100*1048576)
#define nTPB 32
#define BLKS 2

__device__ unsigned int buffer_index = 0;

__global__ void update_buffer(int *buffer_data){
  const unsigned int size_of_my_thread_data = 1;
  unsigned int my_buffer_offset = atomicAdd(&buffer_index, size_of_my_thread_data);
  assert((my_buffer_offset+size_of_my_thread_data) < DSIZE);
  int my_thread_data[size_of_my_thread_data];
  my_thread_data[0] = (blockIdx.x*10000) + threadIdx.x;
  memcpy(buffer_data+my_buffer_offset, my_thread_data, size_of_my_thread_data*sizeof(int));
}

int main(){

  int *h_buffer_data, *d_buffer_data;
  cudaMalloc(&d_buffer_data, sizeof(int)*DSIZE);
  update_buffer<<<BLKS, nTPB>>>(d_buffer_data);
  unsigned int result_size;
  cudaMemcpyFromSymbol(&result_size, buffer_index, sizeof(unsigned int));
  h_buffer_data = (int *)malloc(sizeof(int)*result_size);
  cudaMemcpy(h_buffer_data, d_buffer_data, result_size*sizeof(int),cudaMemcpyDeviceToHost);
  for (int i = 0; i < result_size; i++)
    printf("%d\n", h_buffer_data[i]);
  return 0;
}