c++ - 在我的运行时cuda程序中,cpu和gpu可以异步计算,但不能协同计算,为什么?

标签 c++ cuda

在我的运行时cuda程序中,cpu和gpu可以异步计算,但不能协同计算,为什么?

我测量了程序的时间,总时间是 cpu 计算时间和 gpu 计算时间的总和。通过可视化配置文件,我发现 gpu 在 cpu 完成之前不计算。我的目的是 cpu 计算与 gpu 计算同时进行。

平台: 窗口 10
库达 7.5
vs2013

在 Debug模式下编译的代码(没有优化)

#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 s\n", t1/1000);
    printf("clock cpu:%f s\n",(float) (ctt - ct)/CLOCKS_PER_SEC);
    printf("clock total time: %f s\n", (float)(sss - ss) / CLOCKS_PER_SEC);

    cudaEventDestroy(start);
    cudaEventDestroy(stop1);
    cudaDeviceReset();

}

最佳答案

这里有几个(潜在的)问题:

  • 如果您使用的是 WDDM 驱动程序(而不是 TCC 驱动程序),内核启动会进行批处理以减少 WDDM 驱动程序较高启动开销的影响。这意味着驱动程序将推迟 addKernel() 的启动以等待更多工作,直到它遇到 cudaEventSynchronize() 调用。¹⁾ 但是此时 comput() 已经完成了。

    因此,在您的示例中,CPU 和 GPU 工作确实不会并行运行,但是 GPU 上的 addKernel() 实际上在 after comput() 上运行中央处理器。
    您可以通过 inserting a call to cudaStreamQuery(0) 阻止(进一步)批处理并强制立即启动 addKernel()在调用 comput() 之前。

  • addKernel()compute() 没有外部可见的效果(它们只设置局部变量 a)并且可能被编译器完全优化掉。在 Debug模式下编译可能不会阻止所有这些优化。这将使演示异步执行变得更加困难,因为您只测量内核启动和计时开销。
    因此,请将它们替换为执行实际工作的代码,例如对 vector 求和,并将结果存储到全局变量。

  • 正如 halelf 在他的回答中指出的那样,分析器可能会在特定条件下同步启动内核。


¹⁾ 如果一段时间内没有进一步的工作,等待也可能超时并且 addKernel() 可能会在 cudaEventSynchronize() 调用之前启动。

关于c++ - 在我的运行时cuda程序中,cpu和gpu可以异步计算,但不能协同计算,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40969977/

相关文章:

c++ - 矩阵矩形部分转置Cuda

c++ - CUDA cuFFT 架构 x86_64 的 undefined symbol

cuda - 如何从代码的主机部分获取 GPU 的当前计算能力?

c++ - 从子类 : gcc vs msvc 访问 protected 成员

c++ - 如何使用boost属性树使用boost解析json字符串中数组中的元素?

c++ - 如何从C函数访问C++类数据成员

qt - 在 Ubuntu 12.04 上将 CUDA 与 Qt 集成

cuda - 高性能计算术语 : What's a GF/s?

c++ - 如果A类的成员函数改变了,A类的客户端二进制文件需要重建吗?

c++ - 用 dft 粗略估计质心