比较 CPU 和 GPU 中内存范围的规范方法是什么

What is the canonical way to compare memory ranges in the CPU and in the GPU

我必须连续范围(指针 + 大小),一个在 GPU 中,一个在 CPU 中,我想比较它们是否相等。

比较这些范围是否相等的规范方法是什么?

my_cpu_type cpu;  // cpu.data() returns double*
my_gpu_type gpu;  // gpu.data() returns thrust::cuda::pointer<double>

thrust::equal(cpu.data(), cpu.data() + cpu.size(), gpu.data());

给出了非法内存访问。 我也试过了

thrust::equal(
   thrust::cuda::par // also thrust::host
   , cpu.data(), cpu.data() + cpu.size(), gpu.data()
);

一般情况下用推力是做不到你想象的那样的。 Thrust 不在混合后端中执行算法。您必须使用设备后端,在这种情况下,所有数据都需要在设备上(或从设备代码访问,见下文),或者使用主机后端,在这种情况下,所有数据都需要在主机上。

因此您将被迫将数据从一侧复制到另一侧。成本应该相似(将主机数组复制到设备,或将设备数组复制到主机)所以我们更喜欢复制到设备,因为设备比较可以更快。

如果您有幸将主机数组置于固定缓冲区中,那么就可以执行您建议的操作。

对于一般情况,这样的事情应该有效:

thrust::host_vector<double>   cpu(size);
thrust::device_vector<double> gpu(size);

thrust::device_vector<double> d_cpu = cpu;
bool are_equal = thrust::equal(d_cpu.begin(), d_cpu.end(), gpu.begin());

除了 Robert 的有效答案外,我认为您在尝试使用涉及 GPU 计算的 C++-STL-like 代码时走错了路。

问题不仅仅是指针指向哪里的问题。 std::equal 之类的东西本质上是顺序的。即使它的实现涉及并行性,假设仍然是一个计算,即尽快启动,阻塞调用线程,并将结果返回给调用线程以继续其工作。虽然这可能就是您想要的,但我猜想在大多数情况下,它可能不是。我认为 thrust 的方法让开发人员觉得他们正在编写“C++ STL 代码,但使用 GPU”(大部分)是被误导的。

如果集成了 GPU 任务图、C++ future/async/promise 机制,也许还有 taskflow 或其他框架之类的东西,那可能会以某种方式变得更“规范”这样做。