为啥在 GPU 中执行方法的时间比在混合器项目中的 CPU 中执行的时间更多?

Posted

技术标签:

【中文标题】为啥在 GPU 中执行方法的时间比在混合器项目中的 CPU 中执行的时间更多?【英文标题】:Why the time to execute a method in GPU is more compare to in CPU in hybridizer projects?为什么在 GPU 中执行方法的时间比在混合器项目中的 CPU 中执行的时间更多? 【发布时间】:2021-01-28 14:33:04 【问题描述】:

我正在运行 hybridizer-basic-samples 的 Hello World 示例。但是在 GPU 上执行的时间比在 Cpu 上的时间要多。

    [EntryPoint("run")]
    public static void Run(int N, double[] a, double[] b)
    
        Parallel.For(0, N, i =>  a[i] += b[i]; );
    

    static void Main(string[] args)
    
        int N = 1024 * 1024 * 16;
        double[] acuda = new double[N];
        double[] adotnet = new double[N];
        double[] b = new double[N];
        Random rand = new Random();
        for (int i = 0; i < N; ++i)
        
            acuda[i] = rand.NextDouble();
            adotnet[i] = acuda[i];
            b[i] = rand.NextDouble();
        

        cudaDeviceProp prop;
        cuda.GetDeviceProperties(out prop, 0);
        HybRunner runner = HybRunner.Cuda().SetDistrib(prop.multiProcessorCount * 16, 128);
        dynamic wrapped = runner.Wrap(new Program());

        // run the method on GPU
        var watch = System.Diagnostics.Stopwatch.StartNew();
        wrapped.Run(N, acuda, b);
        watch.Stop();
        Console.WriteLine($"Execution Time: watch.ElapsedMilliseconds ms");

        // run .Net method
        var watch2 = System.Diagnostics.Stopwatch.StartNew();
        Run(N, adotnet, b);
        watch2.Stop();
        Console.WriteLine($"Execution Time: watch2.ElapsedMilliseconds ms");
    

当我运行程序时,GPU 中 Run() 的执行时间总是超过 .Net 方法。就像 GPU 执行它需要 818 毫秒,但对于 cpu,89 毫秒。谁能解释一下原因?

【问题讨论】:

在基准测试之前进行预热运行,以确保您没有对抖动进行基准测试。还要确保您在没有附加调试器的情况下在发布模式下进行基准测试。一旦你做了这两件事,看看结果是否会有所不同。 更糟糕的是,您正在对动态调用的第一次调用 (wrapped.Run) 进行基准测试,因此您实际上是在对启动时的编译器和解析动态调用进行基准测试。 【参考方案1】:

正如@InBetween 所述,您可能正在测量编译器开销。做一个预热通道让所有代码首先编译是一个很好的做法。或者使用类似 benchmarking.net 的东西来为你做这件事。

另一个可能的原因是开销。在 GPU 上运行时,系统需要将输入数据复制到 GPU 内存,然后再次将结果复制回来。可能还会涉及其他费用。将数字相加是一个非常简单的操作,因此处理器很可能可以以最大理论速度运行。

让我们做一些粗略的计算。假设 CPU 每个时钟可以执行 4 次加法(即 AVX256 可以执行的操作)。 4 * 8 字节/双精度 = 32 字节/时钟,以及 4*10^9 时钟/秒。这提供了 128 GB/s 的处理速度。这明显高于 16GB/s 的 PCIe 3 x16 带宽。由于其他限制,您可能无法达到这个速度,但这表明限制因素可能不是处理器本身,因此使用 GPU 可能不会改善情况。

当使用对每个数据项进行更多处理的更复杂的算法时,GPU 处理应该显示出更好的收益。

【讨论】:

以上是关于为啥在 GPU 中执行方法的时间比在混合器项目中的 CPU 中执行的时间更多?的主要内容,如果未能解决你的问题,请参考以下文章

我的 OpenCL 代码在 GPU 上比在 CPU 上慢

为啥这个算法在 python 中的运行速度比在 C++ 中快得多?

在 GPU 上计算积分图像真的比在 CPU 上更快吗?

为啥在 VB.NET 中使用 DeviceIoControl 进行文件枚举比在 C++ 中更快?

为啥通过 django QuerySet 进行查询比在 Django 中使用游标慢得多?

HTML5 Canvas 在 Firefox 上比在 Chrome 上更快!为啥?