2

这是来自http://caffe.berkeleyvision.org/tutorial/net_layer_blob.html的示例

我有点迷路了。我应该从这个例子中推断出什么?

// Assuming that data are on the CPU initially, and we have a blob.
const Dtype* foo;
Dtype* bar;
foo = blob.gpu_data(); // data copied cpu->gpu.
foo = blob.cpu_data(); // no data copied since both have up-to-date contents.
bar = blob.mutable_gpu_data(); // no data copied.
// ... some operations ...
bar = blob.mutable_gpu_data(); // no data copied when we are still on GPU.
foo = blob.cpu_data(); // data copied gpu->cpu, since the gpu side has modified the data
foo = blob.gpu_data(); // no data copied since both have up-to-date contents
bar = blob.mutable_cpu_data(); // still no data copied.
bar = blob.mutable_gpu_data(); // data copied cpu->gpu.
bar = blob.mutable_cpu_data(); // data copied gpu->cpu.
4

1 回答 1

2

这个片段是为了解释 Caffe 的 Blob 类的一个特性,它可以保护用户免受 CPU<->GPU 内存传输的细节的影响。

我试图详细说明代码中的注释:

它假定您已经声明了一个 Blob 对象并填充了数据。数据代表什么无关紧要。此片段中缺少 Blob 对象的实际声明及其初始化。

// Assuming that data are on the CPU initially, and we have a blob.
const Dtype* foo;
Dtype* bar;

由于填充 blob 的数据驻留在 CPU 内存中,因此在 GPU 设备上使用它需要传输。

foo = blob.gpu_data(); // data copied cpu->gpu.

但是,如果您要将相同的数据复制到 CPU 内存上的其他位置,则 Blob 对象将不必执行 CPU<->GPU 传输所需的昂贵的复制操作。

foo = blob.cpu_data(); // no data copied since both have up-to-date contents.

使用驻留在 GPU 内存中的数据初始化“条形”对象。它已经复制了一次。无需重复昂贵的复制操作。

bar = blob.mutable_gpu_data(); // no data copied.
// ... some operations ...
bar = blob.mutable_gpu_data(); // no data copied when we are still on GPU.

Blob 类跟踪 CPU 和 CPU 副本是否相同,或者是否已修改,需要更新副本以保持它们相同。

foo = blob.cpu_data(); // data copied gpu->cpu, since the gpu side has modified the data
foo = blob.gpu_data(); // no data copied since both have up-to-date contents

现在我们只是来回走动,看看什么会触发一个副本,什么会回退到数据的缓存副本上。

bar = blob.mutable_cpu_data(); // still no data copied.
bar = blob.mutable_gpu_data(); // data copied cpu->gpu.
bar = blob.mutable_cpu_data(); // data copied gpu->cpu.
于 2015-07-14T12:54:43.357 回答