C 库达;使用设备内存共享
块中的每个线程可以有不同的结果集(和大小)。目前,我正在分配固定大小的设备内存;按线程思考 也就是说,对于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_计数,将数据写入共享内存块,解锁互斥锁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_结构相乘 在现实世界中,这意味着设备内存的巨大浪费,因为有些集接
[问题解决了,谢谢,伙计们!]重写内核并调用函数来计算部分所需的点(显然,您必须更改每次启动的块数等)
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;
}