我有一個由多個CPU線程組成的應用程序,每個CPU線程在我的GPU上的相同cudaContext中創建一個單獨的cudaStream。我有一臺特斯拉K20c。我使用Windows 7 64位和Cuda 5.5。多線程CPU CUDA應用程序在調用CudaFree時不會異步
這裏是我的代碼:
#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註釋掉我實現以下目的:
這是除了我有一個內存完美泄漏,因爲我沒有使用cudaFree和cudaFreeHost。當我使用cudaFree和cudaFreeHost我得到以下結果:
這是不好的。當使用cudaFree時,一些流等待其他流首先完成,一些流異步工作。我假設這是因爲cudaFree不是異步的,但這並不能解釋爲什麼它有時會像在前三個內核中那樣工作,但在其他時間沒有。如果cudaFree被調用,但GPU已經在忙着做其他事情,可以讓CPU繼續計算,並讓cudaFree自動獲得第一次機會?是否有另一種方法來解決這個問題?謝謝你提供的所有幫助!