gpt4 book ai didi

c++ - 调用 CudaFree 时多线程 CPU CUDA 应用程序不是异步的

转载 作者:行者123 更新时间:2023-11-28 07:16:17 26 4
gpt4 key购买 nike

我有一个由多个 CPU 线程组成​​的应用程序,每个 CPU 线程在我的 GPU 上的同一个 cudaContext 中创建一个单独的 cudaStream。我有一辆特斯拉 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 被注释掉时,我得到了以下结果:

nVidia Visual Profiler Async nVidia Visual Profiler Async bottom

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

nVidia Visual Profiler sync top nvidia visual Profiler sync bottom

这很糟糕。使用 cudaFree 时,一些流先等待其他流完成,而一些流异步工作。我假设这是因为 cudaFree 不是异步的,这很好,但这并不能解释为什么它有时像在前三个内核中那样工作,但在其他时候却不行?如果调用了 cudaFree 但 GPU 已经忙于做其他事情,是否可以让 CPU 继续计算并让 cudaFree 在它获得第一个机会时自动发生?还有另一种方法可以解决这个问题吗?感谢您提供的任何帮助!

最佳答案

是的,cudaFree 不是异步的。 Niether 是 cudaMalloc

在时间关键代码之前预先进行所有分配,并在最后进行自由操作。

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

相同的评论适用于流创建。我不会费心在飞行中创建和销毁它们。创建任意数量,并在完成之前重复使用它们。

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

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com