为什么cuda_free的开销如此之高?(是因为调零吗?)
我观察到cudaFree操作花费的时间长得令人无法接受。为了验证它,我编写了一个简单的微基准测试代码来测试cudaFree开销。它显示出类似的趋势 第一步:为什么cuda_free的开销如此之高?(是因为调零吗?),cuda,profiling,Cuda,Profiling,我观察到cudaFree操作花费的时间长得令人无法接受。为了验证它,我编写了一个简单的微基准测试代码来测试cudaFree开销。它显示出类似的趋势 第一步:cudaMallocManaged 不需要那么长时间。实际上,仅对于CudamAllocManager而言,它小于1ms 第二步:init 要初始化malloced内存区域,调用init函数。而且它也不需要少于1ms的时间 第三步:cudaFree 现在,开销出现了这需要很多时间。还有一件事越大,内存大小越长。(漂亮的线性) 问题是“为什么c
cudaMallocManaged
不需要那么长时间。实际上,仅对于CudamAllocManager而言,它小于1ms
第二步:init
要初始化malloced内存区域,调用init函数。而且它也不需要少于1ms的时间
第三步:cudaFree
现在,开销出现了这需要很多时间。还有一件事越大,内存大小越长。(漂亮的线性)
问题是“为什么cudaFree会有如此巨大的开销?它是否会因为安全问题而用零填充整个内存区域?或者它所经过的任何其他关键路径?”
这是代码和测量结果。
提前感谢:)
- 奇怪的是,8192MB和16384MB不仅对cudaManagedMalloc和init显示小于0毫秒,而且对cudaFree显示小于0毫秒
cudaFree
的时间来自之前的异步操作
它是否为安全问题用零填充整个内存区域
没有
或者它所走过的任何其他关键路径
不,除非它要求设备处于空闲状态,而您的情况并非如此
让我们修复代码中最明显的问题:
// measuring initialization
ts1 = getTimeDiff(baseTime);
init<<<1,1>>>(dptr, num_bytes_);
cudaDeviceSynchronize(); // Wait until the GPU is idle
ts2 = getTimeDiff(baseTime);
您可以看到,您假设的时间是cudaFree
是完全串行init
内核运行所需的时间。cudamalocmanaged
和cudaFree
都会随着分配规模的增加而占用更多的时间,但这并不是不合理的
奇怪的是,8192MB和16384MB不仅对cudaManagedMalloc和init显示小于0毫秒,而且对cudaFree显示小于0毫秒
那是因为没有任何东西在运行。如果您使用correct,您将看到一切都在失败,并且出现内存不足的运行时错误
为什么cudaFree有这么大的开销
没有。您使用的计时方法不正确,您归因于cudaFree
的时间来自之前的异步操作
它是否为安全问题用零填充整个内存区域
没有
或者它所走过的任何其他关键路径
不,除非它要求设备处于空闲状态,而您的情况并非如此
让我们修复代码中最明显的问题:
// measuring initialization
ts1 = getTimeDiff(baseTime);
init<<<1,1>>>(dptr, num_bytes_);
cudaDeviceSynchronize(); // Wait until the GPU is idle
ts2 = getTimeDiff(baseTime);
您可以看到,您假设的时间是cudaFree
是完全串行init
内核运行所需的时间。cudamalocmanaged
和cudaFree
都会随着分配规模的增加而占用更多的时间,但这并不是不合理的
奇怪的是,8192MB和16384MB不仅对cudaManagedMalloc和init显示小于0毫秒,而且对cudaFree显示小于0毫秒
那是因为没有任何东西在运行。如果您使用了correct,您将看到所有操作都会失败,并且出现内存不足的运行时错误。非常感谢您的详细回复。我不知道“cudaDeviceSynchronize()”部分。现在我看到了开销的根源。。为了确保我正确理解您的答案,主机将内核或CUDAAPI调用发送到GPU,而不管它是否实际完成。如果没有显式同步,主机就无法知道API或内核是否实际完成。默认情况下,内核是异步的。其他API可能会阻塞或异步,具体取决于API。它们都有文件记录。在这种情况下,cudaFree不是异步的,因此它会阻塞,直到设备空闲。并累计进程中运行的内核的挂钟时间。CUDA有一个名为events的工具,如果您需要它,它可以用来检测单个操作或操作组的同步、回调、计时等。再次感谢您的输入。我清楚地看到后面发生了什么。我想我也需要查找事件部分。非常感谢您的详细回复。我不知道“cudaDeviceSynchronize()”部分。现在我看到了开销的根源。。为了确保我正确理解您的答案,主机将内核或CUDAAPI调用发送到GPU,而不管它是否实际完成。如果没有显式同步,主机就无法知道API或内核是否实际完成。默认情况下,内核是异步的。其他API可能会阻塞或异步,具体取决于API。它们都有文件记录。在这种情况下,cudaFree不是异步的,因此它会阻塞,直到设备空闲。并累计进程中运行的内核的挂钟时间。CUDA有一个名为events的工具,如果您需要它,它可以用来检测单个操作或操作组的同步、回调、计时等。再次感谢您的输入。我清楚地看到后面发生了什么。我想我也需要查找事件部分。
// measuring initialization
ts1 = getTimeDiff(baseTime);
init<<<1,1>>>(dptr, num_bytes_);
cudaDeviceSynchronize(); // Wait until the GPU is idle
ts2 = getTimeDiff(baseTime);
$ nvcc -std=c++11 -o fliestime fliestime.cu
$ ./fliestime
sizeof(size_t): 8
sizeof(unsigned int): 4
sizeof(int): 4
sizeof(long): 8
cudaMallocManaged, memory_size:1MB, duration:102
init, memory_size:1MB, duration:2
cudaFree, memory_size:1MB, duration:1
cudaMallocManaged, memory_size:2MB, duration:0
init, memory_size:2MB, duration:5
cudaFree, memory_size:2MB, duration:0
cudaMallocManaged, memory_size:4MB, duration:1
init, memory_size:4MB, duration:8
cudaFree, memory_size:4MB, duration:0
cudaMallocManaged, memory_size:8MB, duration:1
init, memory_size:8MB, duration:17
cudaFree, memory_size:8MB, duration:1
cudaMallocManaged, memory_size:16MB, duration:1
init, memory_size:16MB, duration:33
cudaFree, memory_size:16MB, duration:1
cudaMallocManaged, memory_size:32MB, duration:3
init, memory_size:32MB, duration:65
cudaFree, memory_size:32MB, duration:2
cudaMallocManaged, memory_size:64MB, duration:5
init, memory_size:64MB, duration:121
cudaFree, memory_size:64MB, duration:4
cudaMallocManaged, memory_size:128MB, duration:9
init, memory_size:128MB, duration:219
cudaFree, memory_size:128MB, duration:8
cudaMallocManaged, memory_size:256MB, duration:17
init, memory_size:256MB, duration:427
cudaFree, memory_size:256MB, duration:18
cudaMallocManaged, memory_size:512MB, duration:34
init, memory_size:512MB, duration:854
cudaFree, memory_size:512MB, duration:35
cudaMallocManaged, memory_size:1024MB, duration:67
init, memory_size:1024MB, duration:1709
cudaFree, memory_size:1024MB, duration:70
cudaMallocManaged, memory_size:2048MB, duration:133
init, memory_size:2048MB, duration:3418
cudaFree, memory_size:2048MB, duration:141
cudaMallocManaged, memory_size:4096MB, duration:786
init, memory_size:4096MB, duration:4
cudaFree, memory_size:4096MB, duration:0
cudaMallocManaged, memory_size:8192MB, duration:0
init, memory_size:8192MB, duration:0
cudaFree, memory_size:8192MB, duration:0
cudaMallocManaged, memory_size:16384MB, duration:0
init, memory_size:16384MB, duration:0
cudaFree, memory_size:16384MB, duration:0