I would be extremely helpful to have a clear definition what a device in TensorFlow is exactly. Is a device a single processing unit (no "real" concurrency possible)?
You can define as many devices as you want by doing the following:
config = tf.ConfigProto(device_count={"CPU": 2},
inter_op_parallelism_threads=2,
intra_op_parallelism_threads=1)
sess = tf.Session(config=config)
How is it possible that you can define as many devices as you want despite having only one processor with 4 cores?
答案 0 :(得分:14)
评论太长了(也许@mrry或@keveman可以给出官方定义),但这里有一些观察:
tf.device("gpu:0")
设备上调度的操作可以将其数据保存在主存储器(即物理CPU设备)中,因此在实践中有时会违反逻辑设备边界。这是您在整数HostMemory
here等操作中看到的Add
注释。这允许人们在逻辑设备GPU上执行形状操作之类的操作,并避免跨越逻辑设备边界(发送/接收操作),即使数据未存储在物理设备GPU上。device_count={"CPU": m}...intra_op_parallelism_threads=n
创建多个Eigen线程池,每个线程池都有n
个线程,因此您可以手动对图表进行分区,以便并行运行m
ops,其中每个操作都会请求{{1}线程。但是,与物理内核相比,您不能同时运行更多线程,因此这可能会很慢。n
等逻辑设备不是固定的特定内核,因此可以使用任何可用的内核以下是创建8个CPU设备并并行运行2个matmul的示例:https://gist.github.com/yaroslavvb/9a5f4a0b613c79152152b35c0bc840b8
核心图构造如下所示
cpu:0
如果您运行要点,请查看已打印的with tf.device("cpu:0"):
a1 = tf.ones((n, n))
a2 = tf.ones((n, n))
with tf.device("cpu:1"):
a3 = tf.matmul(a1, a2)
with tf.device("cpu:2"):
a4 = tf.matmul(a1, a2)
with tf.device("cpu:3"):
a5 = tf.matmul(a3, a4)
分区图部分,您会看到run_metadata
ops添加了在CPU设备之间传输数据,即类似这样的内容
Send/Recv
因此,您发现partition_graphs {
node {
name: "MatMul_1/_11"
op: "_Recv"
device: "/job:localhost/replica:0/task:0/cpu:3"
attr {
key: "client_terminated"
value {
b: false
}
}
attr {
key: "recv_device"
value {
s: "/job:localhost/replica:0/task:0/cpu:3"
}
}
attr {
key: "send_device"
value {
s: "/job:localhost/replica:0/task:0/cpu:2"
}
}
操作系统已计划将数据从Send
传输到cpu:2
。由于所有CPU设备共享内存,因此该操作系统无法执行任何操作,但如果TensorFlow成为NUMA,则可能会在将来执行某些操作。
此外,您可以在cpu:3
下的浏览器中打开timeline.json
并查看时间
你可以看到它并行运行两个1024x1024矩阵乘法,每个乘法约需85ms,最低可达25 M ops /秒,相当于2年前macbook的单核性能。
另一方面,你可以在6个不同的CPU设备上运行6个这样的矩阵乘法,你会看到类似的东西。
我只有4个物理内核,你看到其中2个操作需要2倍的时间。尽管它们在逻辑chrome://tracing
设备上处于活动状态,但前100毫秒有任何可用的物理内核,因此它们没有取得任何进展。