我在分布式TensorFlow的contrib实现中遇到了问题。为了不使用非相关细节,该解决方案应用特定的消息协议,以便直接从/向源/目标张量使用RDMA写入,以便在CPU上保存内存副本。
假设我有两个方面,A
和B
,而A
希望从B
获得一个张量。协议如下:
A
向REQUEST
发送B
消息。B
在本地查找张量(BaseRendezvousMgr::RecvLocalAsync
)并向META-DATA
发送A
响应。A
使用元数据来分配目标张量,并将ACK
发送到包含目标地址的B
。B
接收ACK
,并执行远程DMA写入目标地址。在REQUEST
和ACK
之间,B
通过将局部张量保存在局部地图中来保持局部张量(和Ref()> 0)(REQUEST
将张量复制到局部地图,ACK
从地图中弹出它)。
为验证我的解决方案,我在每一步都添加了校验和计算。偶尔,我看到校验和在REQUEST
和ACK
之间变化。当我与两个工人运行PS时会发生这种情况:
REQUEST
到工人0。ACK
到工人0。REQUEST
。ACK
。每行的最后一个值是校验和。错误发生在大约50%的时间。我总是在第4行看到它。
我还看到有问题的张量为所有step-id都有一个共享缓冲区(这是给定的。我无法控制它)。所以很可能其他一些线程改变了第3行和第4行之间的张量内容,这是我想要防止的。
那么问题是如何?什么阻止了内容在第1行和第2行,第2行和第3行之间发生变化?要强调的是,第3行和第4行之间经过的时间小于0.04秒,而在2和3之间经过的时间几乎是2.5秒。
谢谢你的帮助。如果需要,将发布代码。
你是否为共享缓冲区使用tf.Variable?如果是这样,使用tfe.Variable(以启用合理的读写语义)或tf.get_variable(...,use_resource = True)来构造它将使任何同步问题消失。
否则,如果不了解生成图的更多信息,这很难理解。