Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Memory 如何减少CudaMemcpy开销_Memory_Cuda_Gpu - Fatal编程技术网

Memory 如何减少CudaMemcpy开销

Memory 如何减少CudaMemcpy开销,memory,cuda,gpu,Memory,Cuda,Gpu,我有一个大小为3000的数组。该数组包含0和1。我想找到第一个数组位置,该位置从第0个索引开始存储了1。我将此数组传输到主机,并在设备上计算此数组。然后我在主机上按顺序计算索引。在我的程序中,我想重复执行此计算4000次或更多次。我想减少这个过程所花费的时间。有没有其他方法可以做到这一点,这个数组实际上是在GPU上计算的,所以我每次都要传输它 int main() { for(int i=0;i<4000;i++) { cudaMemcpy(A,dev_A,sizeof(int)*

我有一个大小为3000的数组。该数组包含0和1。我想找到第一个数组位置,该位置从第0个索引开始存储了1。我将此数组传输到主机,并在设备上计算此数组。然后我在主机上按顺序计算索引。在我的程序中,我想重复执行此计算4000次或更多次。我想减少这个过程所花费的时间。有没有其他方法可以做到这一点,这个数组实际上是在GPU上计算的,所以我每次都要传输它

int main()
{
for(int i=0;i<4000;i++)
{
    cudaMemcpy(A,dev_A,sizeof(int)*3000,cudaMemcpyDeviceToHost);
    int k;
    for(k=0;k<3000;k++)
    {
        if(A[k]==1)
        {
            break;
        } 
    }
    printf("got k is %d",k);
}
} 
}

intmain()
{
int pos=int_MAX,i;
int*d_pos;
int A[大小];
int*d_A;

对于(i=0;i如果您在GPU上运行内核4000次,则可能需要通过不同的流在内核上使用异步执行。使用cudaMemCpyAsync可能会更快,因为它是主机的一个非阻塞函数(在执行内核M次的情况下)

快速介绍流和异步执行:

流和并发:


希望这能帮助…

相对于复制操作,内核生成设备数组内容的速度是多少?是快还是慢?当前形式的代码没有真正意义。因此我假设在循环中调用
cudaMemcpy
之前,内核已启动(每次用新数据填充
dev_A
)-这是否正确?是否可以替换将要更新的设备阵列?是的,我有一个内核填充dev_a阵列。实际上,我的任务是从0中查找第一个索引,其中包含存储在阵列a中此位置的1,该数组填充在GPU上。我想启动内核并使用atomicMin操作在GPU上计算索引n我将该变量复制到主机,这与复制数组大小=3000的时间相同。因此,我的问题是,是否有可能替换内核写入的设备数组。如果不可能,可能通过某种迭代依赖关系,您的答案将不是一个选项。如果有可能,当然这是一个尝试od方式。为什么单变量传输时间和阵列大小3000传输时间大致相同?
__global__ void kernel(int *A,int *d_pos)
{
int thread_id=threadIdx.x+blockIdx.x*blockDim.x;
while(thread_id<SIZE)
{
    if(A[thread_id]==INT_MIN)
    {
        *d_pos=thread_id;
        return;
    }
    thread_id+=1;   
}
__global__ void kernel1(int *A,int *d_pos)
{
int thread_id=threadIdx.x+blockIdx.x*blockDim.x;
if(A[thread_id]==INT_MIN)
{
    atomicMin(d_pos,thread_id);
}
int main()
{
int pos=INT_MAX,i;
int *d_pos;
int A[SIZE];
int *d_A;
for(i=0;i<SIZE;i++)
{
    A[i]=78;
}
A[SIZE-1]=INT_MIN;
cudaMalloc((void**)&d_pos,sizeof(int));
cudaMemcpy(d_pos,&pos,sizeof(int),cudaMemcpyHostToDevice);
cudaMalloc((void**)&d_A,sizeof(int)*SIZE);
cudaMemcpy(d_A,A,sizeof(int)*SIZE,cudaMemcpyHostToDevice);

cudaEvent_t start_cp1,stop_cp1;
    cudaEventCreate(&stop_cp1);
    cudaEventCreate(&start_cp1);
    cudaEventRecord(start_cp1,0);

kernel1<<<BLOCKS,THREADS>>>(d_A,d_pos);

cudaEventRecord(stop_cp1,0);
    cudaEventSynchronize(stop_cp1);
    float elapsedTime_cp1;
    cudaEventElapsedTime(&elapsedTime_cp1,start_cp1,stop_cp1);
    cudaEventDestroy(start_cp1);
    cudaEventDestroy(stop_cp1);
    printf("\nTime taken by kernel is  %f\n",elapsedTime_cp1);
cudaDeviceSynchronize();

cudaEvent_t start_cp,stop_cp;
    cudaEventCreate(&stop_cp);
    cudaEventCreate(&start_cp);
    cudaEventRecord(start_cp,0);

cudaMemcpy(A,d_A,sizeof(int)*SIZE,cudaMemcpyDeviceToHost);

    cudaEventRecord(stop_cp,0);
    cudaEventSynchronize(stop_cp);
    float elapsedTime_cp;
    cudaEventElapsedTime(&elapsedTime_cp,start_cp,stop_cp);
    cudaEventDestroy(start_cp);
    cudaEventDestroy(stop_cp);
    printf("\ntime taken by copy of an array is  %f\n",elapsedTime_cp);






    cudaEvent_t start_cp2,stop_cp2;
    cudaEventCreate(&stop_cp2);
    cudaEventCreate(&start_cp2);
    cudaEventRecord(start_cp2,0);

    cudaMemcpy(&pos,d_pos,sizeof(int),cudaMemcpyDeviceToHost);

    cudaEventRecord(stop_cp2,0);
    cudaEventSynchronize(stop_cp2);
    float elapsedTime_cp2;
    cudaEventElapsedTime(&elapsedTime_cp2,start_cp2,stop_cp2);
    cudaEventDestroy(start_cp2);
    cudaEventDestroy(stop_cp2);
    printf("\ntime taken by copy of a variable is  %f\n",elapsedTime_cp2);


cudaMemcpy(&pos,d_pos,sizeof(int),cudaMemcpyDeviceToHost);
printf("\nminimum index is %d\n",pos);
return 0;
}