为啥在 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 中执行的时间更多?的主要内容,如果未能解决你的问题,请参考以下文章
为啥这个算法在 python 中的运行速度比在 C++ 中快得多?
为啥在 VB.NET 中使用 DeviceIoControl 进行文件枚举比在 C++ 中更快?