在我的CUDA运行时间计划中,CPU和GPU可以异步计算,但不能合作地计算
In my cuda program of runtime ,the cpu and gpu can compute Asynchronously,but not cooperatively,why?
在我的CUDA程序程序中,CPU和GPU可以异步计算,但不能合作计算,为什么?
i测量程序的时间,总时间是CPU计算时间和GPU计算时间的总和时间。通过视觉轮廓,我发现GPU在CPU完成之前不计算。我的目的是CPU计算为GPU计算的同一时间。
平台:窗口10
CUDA 7.5
VS2013
以调试模式编译的代码(无优化)
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include<time.h>
__global__ void addKernel()
{
int a ;
for (int i = 0; i < 10000;i++)
for (int j = 0; j < 10000;j++)
a = i;
}
void comput()
{
int a = 1;
for (int i = 0; i < 10000;i++)
for (int j = 0; j < 10000; j++)
{
for (int k = 0; k < 100;k++)
a = j;
}
}
int main()
{
cudaSetDevice(0);
cudaEvent_t start, stop1;
cudaEventCreate(&start);
cudaEventCreate(&stop1);
clock_t ss = clock();
cudaEventRecord(start,0);
addKernel<<<1,64>>>();
cudaEventRecord(stop1,0);
clock_t ct = clock();
comput();
clock_t ctt = clock();
cudaEventSynchronize(stop1);
cudaDeviceSynchronize();
clock_t sss = clock();
float t1;
cudaEventElapsedTime(&t1, start, stop1);
printf("clock GPU :%.4f sn", t1/1000);
printf("clock cpu:%f sn",(float) (ctt - ct)/CLOCKS_PER_SEC);
printf("clock total time: %f sn", (float)(sss - ss) / CLOCKS_PER_SEC);
cudaEventDestroy(start);
cudaEventDestroy(stop1);
cudaDeviceReset();
}
在这里有几个问题(可能):
-
如果您使用的是WDDM驱动程序(与TCC驱动程序相反),则将划分内核,以减少WDDM驱动程序更高的启动开销的效果。这意味着驾驶员将推迟
addKernel()
的发布等待更多工作,直到遇到cudaEventSynchronize()
CALL.TARCE.T。但是,到此时comput()
已经完成。
因此,在您的示例中,CPU和GPU的工作确实不同行,但是GPU上的addKernel()
实际上在CPU上comput()
之后运行。
您可以通过在致电comput()
之前插入cudaStreamQuery(0)
的呼叫来防止(进一步)批处理并强制施加addKernel()
。 -
addKernel()
和compute()
没有外部可见效果(它们仅设置局部变量a
),并且可以由编译器完全优化。在调试模式下编译可能不会阻止所有这些优化。这将使您只能测量内核启动和正时开销,因此很难证明异步执行。
因此,将它们替换为执行真实工作的代码,例如求和向量,并将结果存储到全局变量中。 -
正如Halfelf在他的答案中指出的那样,Profiler可以在某些条件下同步启动内核。
⁾如果在一段时间内没有进一步的工作,等待也可能超时,并且addKernel()
可能会在cudaEventSynchronize()
呼叫之前启动。
来自CUDA编程指南:
程序员可以通过设置cuda_launch_blocking_blocking环境变量可变量为1的所有CUDA应用程序的内核启动的异步性启动的异步性。。
内核启动是同步的,如果通过Profiler(Nsight,Visual Profiler)收集硬件计数器,除非启用并发的内核分析。如果异步内存副本涉及未锁定的主机存储器,则它们也将是同步的。
同样,如果没有优化,主机功能将运行很长时间,也许是百万次内核。如果有优化,它实际上不会运行并立即返回。
我建议尝试分别使用CUDA_LAUNCH_BLOCKING=1
和CUDA_LAUNCH_BLOCKING=0
运行二进制,以测试运行时间。还将内核和主机功能修改为有意义的功能。
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 递归函数计算序列中的平方和(并输出过程)
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的字符计数代码计算错误.为什么
- 在计算中使用二的幂有多有利可图
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何计算文件中的"columns"数?
- 计算排序向量的向量中唯一值的计数
- 如何使用 std::累积在 C++ 中计算总和立方体
- 使用Qt C++计算类似Git的SHA1哈希
- OpenCV C++.快速计算混淆矩阵
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- C++如何计算用户输入的数字中的偶数位数
- 如何计算数据类型的范围,例如int
- 类似枚举的计算常量
- 使用异步/期货并行和并发计算向量的范数
- 在我的CUDA运行时间计划中,CPU和GPU可以异步计算,但不能合作地计算
- 斐波那契的异步计算比序列计算慢
- 在 boost asio 异步服务器中执行计算 taks
- 是更好的同步或异步从boost asio时,有大量的计算和推/弹出线程安全容器