我有一个由多个CPU线程组成的应用程序,其中每个CPU线程在我的GPU上的同一cudaContext中创建一个单独的cudaStream。我有一台Tesla K20c。我正在使用Windows 7 64位和Cuda 5.5。

这是我的代码:

#include "gpuCode.cuh"

__global__ void kernelAddConstant1(int *g_a, const int b)
{
    int idx = blockIdx.x * blockDim.x + threadIdx.x;
    g_a[idx] += b;
    for (int i = 0; i < 4000000.0; i++)
    {
        if (i%2 == 0)
        {
            g_a[idx] += 5;
        }
        else
        {
            g_a[idx] -= 5;
        }
    }
}


// a predicate that checks whether each array elemen is set to its index plus b
int correctResult(int *data, const int n, const int b)
{
    for (int i = 0; i < n; i++)
    {
        if (data[i] != i + b)
        {
            return 0;
        }
    }
    return 11;
}

int gpuDo()
{
    cudaSetDevice(0);
    cudaStream_t stream;
    cudaStreamCreate( &stream );

    int *a;
    int *d_a;

    unsigned int n;
    unsigned int nbytes;

    int b;

    n = 2 * 8192/16;
    nbytes = n * sizeof(int);
    b = 7;      // value by which the array is incremented

    cudaHostAlloc( (void**)&a, nbytes, cudaHostAllocDefault ) ;
    cudaMalloc((void **)&d_a, nbytes);

    for (unsigned int i = 0; i < n; i++)
        a[i] = i;

    unsigned int nbytes_per_kernel = nbytes;
    dim3 gpu_threads(128);  // 128 threads per block
    dim3 gpu_blocks(n / gpu_threads.x);

    cudaMemsetAsync(d_a, 0, nbytes_per_kernel, stream);

    cudaMemcpyAsync(d_a, a, nbytes_per_kernel, cudaMemcpyHostToDevice, stream);


    kernelAddConstant1<<<gpu_blocks, gpu_threads, 0, stream>>>(d_a, b);

    cudaMemcpyAsync(a, d_a, nbytes_per_kernel, cudaMemcpyDeviceToHost, stream);
    cudaStreamSynchronize ( stream ) ;
    cudaStreamDestroy(stream);

    //cudaFree(d_a);

    int bResult = correctResult(a, n, b);

    //if (a)
        //cudaFreeHost(a); // free CPU memory

    return bResult;
}

void gpuEnd()
{
    cudaDeviceReset();
}


当我离开cudaFree和cudaFreeHost时,我获得了以下结果:

c&#43;&#43; - 调用CudaFree时,多线程CPU CUDA应用程序不异步-LMLPHP

c&#43;&#43; - 调用CudaFree时,多线程CPU CUDA应用程序不异步-LMLPHP


这是完美的,除了因为我没有使用cudaFree和cudaFreeHost而导致内存泄漏。当我确实使用cudaFree和cudaFreeHost时,我得到以下结果:

c&#43;&#43; - 调用CudaFree时,多线程CPU CUDA应用程序不异步-LMLPHP

c&#43;&#43; - 调用CudaFree时,多线程CPU CUDA应用程序不异步-LMLPHP


这是不好的。使用cudaFree时,某些流会先等待其他流完成,而某些流将异步工作。我假设这是因为cudaFree不是异步的,这很好,但这不能解释为什么它有时像在调用的前三个内核中一样起作用,而在其他时候却不起作用?如果调用了cudaFree,但是GPU已经忙于做其他事情,是否有可能让CPU继续进行计算,并让cudaFree第一次自动出现?有没有其他方法可以解决此问题?谢谢你提供的所有帮助!

最佳答案

是的,cudaFree不是异步的。虚无是cudaMalloc

在执行时序关键代码之前,请先进行所有分配,最后进行自由操作。

在您的情况下,这应该特别容易,因为每次分配的大小都是相同的。

同样的注释适用于流创建。我不会费心创建和销毁它们。创建所需的任意多个,然后重复使用直到完成。

关于c++ - 调用CudaFree时,多线程CPU CUDA应用程序不异步,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20204936/

10-11 21:22