Многопоточное приложение CPU CUDA не асинхронно при вызове CudaFree

0

У меня есть приложение, состоящее из нескольких потоков ЦП, когда каждый поток ЦП создает отдельный cudaStream в том же cudaContext на моем графическом процессоре. У меня есть 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 комментирует, я достигаю следующего результата:

Изображение 174551Изображение 174551

Это прекрасно, за исключением того, что у меня есть утечка памяти, потому что я не использую cudaFree и cudaFreeHost. Когда я использую cudaFree и cudaFreeHost, я получаю следующий результат:

Изображение 174551Изображение 174551

Это плохо. При использовании cudaFree некоторые потоки ждут, когда другие закончатся, а некоторые потоки работают асинхронно. Я предполагаю, что это потому, что cudaFree не является асинхронным, но это не объясняет, почему он иногда работает, как в первых трех ядрах, но не в другое время? Если вызывается cudaFree, но GPU уже занят чем-то другим, возможно ли, чтобы процессор продолжал вычислять и позволял cudaFree автоматически получать первый шанс? Есть ли другой подход к решению этой проблемы? Спасибо за любую помощь, которую вы можете дать!

Теги:
multithreading
asynchronous
cuda

1 ответ

1
Лучший ответ

Да, cudaFree не является асинхронным. Нитье - cudaMalloc

Делайте все свои распределения перед вашим критически важным кодом времени и выполняйте бесплатные операции в конце.

Это должно быть особенно просто в вашем случае, так как размер распределения одинаковый каждый раз.

Те же комментарии относятся к созданию потока. Я бы не стал создавать и уничтожать их на лету. Создавайте, сколько хотите, и используйте их повторно, пока не закончите.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню