Caffe何时复制数据?

8
 // 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
//1
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

为什么最后两行要复制数据?GPU和CPU难道不都有最新的内容吗?

http://caffe.berkeleyvision.org/tutorial/net_layer_blob.html

1个回答

9

.gpu_data.cpu_data 在数据仅作为输入,且不会被算法修改的情况下使用。 .mutable_*在运行算法时会更新数据本身。

每当调用数据时,它会检查前一个语句是否是可变函数调用,以及是否使用相同的处理器(GPU或CPU)。如果使用相同的处理器,则无需复制数据。如果使用其他处理器,则有可能在先前的.mutable_*调用中更新了数据,因此需要进行数据复制。

编辑1 如果前一条指令是“可变的”,则在当前指令位于不同处理器上时,需要在当前指令之前完成数据复制。

除了特殊的初始条件,即GPU内存中根本没有数据,因此在*_gpu_data()调用之前将发生数据复制,否则不会发生数据复制。


只是为了确保我理解正确:如果上一次获取数据的调用(a)在同一处理器上并且(b)是可变的,则会复制数据?如果是这样,那么对于(1)呢?[请参见更新的问题]。为什么bar = blob.mutable_cpu_data();(在(1)之后的调用)不会复制数据? - user678392
3
已经更新了答案,使其更加清晰。调用after(1)并没有被复制,因为(1)不是可变指令,这意味着数据不会被更新,因此在CPU和GPU中数据将保持相同。 - Anoop K. Prabhu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接