具体来说,如果我有一个继承自OpKernel的Op,并且在其中我有一些私有成员声明class MyOpKernel : public OpKernel {
public:
explicit MyOpKernel(OpKernelConstruction* ctx) : OpKernel(ctx) {
if (!BigRODataObject)
BigRODataObject = some_init_func();
}
void Compute( ... ) { // uses BigRODataObject }
private:
static BRODOType* BigRODataObject = null;
};
。我可以安全地假设此内核的所有实例都将访问相同的静态成员吗?是否所有内核都放在同一个地址空间/进程中的同一台机器/工作者(可能是不同的CPU)上?显然,这不适用于映射到分布式设置中的单独机器的内核。 E.g。
static
最后,在实现OpKernel时,有没有比TTTabBar
更好的方法在相同类型的OpKernel之间共享内存中的一大块只读数据?数据太大,无法在内存中容纳多个副本。
答案 0 :(得分:3)
static
的{{1}}成员在同一进程中该内核的所有实例之间共享。如果您正在运行单个TensorFlow进程,则所有实例(包括分配给CPU或GPU的实例以及来自不同会话的实例)将共享相同的tensorflow::OpKernel
成员。
使用static
成员在会话结束时不会处理破坏,并且不允许在不同的会话中使用不同的对象,所以我不推荐这种风格;然而,替代方案有点复杂。对于共享状态,我们通常使用ResourceMgr
(通过OpKernelContext::resource_manager()
)来存储对象。典型的实现使用"构造函数" op首次使用时实例化对象,拥有它,并输出一个(字符串)句柄。共享状态的用户对句柄采用数据依赖关系,并在static
中查找以访问该对象。然后在"构造函数"时删除该对象。 op被删除。这是用于有状态操作的方法,如ResourceMgr
,tf.Variable
等。