TensorFlow中的设备究竟是什么?

LaL*_*aLa 7 tensorflow

对于明确定义TensorFlow中的设备是完全正确的,我会非常有帮助.设备是单个处理单元(没有"真正的"并发可能)吗?

您可以通过执行以下操作来定义任意数量的设备:

config = tf.ConfigProto(device_count={"CPU": 2},
                    inter_op_parallelism_threads=2,
                    intra_op_parallelism_threads=1)
sess = tf.Session(config=config)
Run Code Online (Sandbox Code Playgroud)

尽管只有一个处理器有4个内核,你怎么可能可以定义任意数量的设备?

Yar*_*tov 17

评论太长了(也许@mrry或@keveman可以给出官方定义),但这里有一些观察:

  • TensorFlow中的逻辑设备是具有自己的内存的计算单元.
  • 当数据跨越设备边界时,TensorFlow调度程序添加发送/接收操作以将数据复制到适当的设备
  • 它是一个逻辑设备,因此您可以拥有比物理设备(核心)更多的逻辑设备,并且可以调度可用"设备"上的某些操作,但是等待物理设备释放.对于CPU设备,您可能拥有比核心更多的线程,因此OS线程调度程序选择在任何给定时刻运行的线程子集
  • 在逻辑tf.device("gpu:0")设备上调度的操作可以将其数据保存在主存储器(即物理CPU设备)中,因此在实践中有时会违反逻辑设备边界.这是HostMemory你在OPS看到像整数注解Add 这里.这允许人们在逻辑设备GPU上执行像形状操作之类的操作,并避免跨越逻辑设备边界(发送/接收操作),即使数据未存储在物理设备GPU上也是如此.
  • 使用device_count={"CPU": m}...intra_op_parallelism_threads=n创建多个具有n线程的Eigen线程池,因此您可以手动对图形进行分区m以并行运行ops,其中每个op都将请求n线程.但是,您不能同时运行比物理内核更多的线程,因此这可能会很慢.
  • 像这样的逻辑设备cpu:0没有固定特定的内核,所以它们可以使用任何可用的内核
  • 您可以通过查看时间轴来了解实际的并行性

以下是创建8个CPU设备并并行运行2个matmul的示例:https://gist.github.com/yaroslavvb/9a5f4a0b613c79152152b35c0bc840b8

核心图构造看起来像这样

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 Code Online (Sandbox Code Playgroud)

如果您运行要点run_metadata,请查看打印的分区图部分,您会看到Send/Recvops添加了在CPU设备之间传输数据,即类似这样的内容

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"
      }
    }
Run Code Online (Sandbox Code Playgroud)

所以你看,有一个Send计划将数据从传输运cpu:2cpu:3.由于所有CPU设备共享内存,因此该操作不会执行任何操作,但如果TensorFlow成为NUMA,则可能会在将来执行某些操作.

此外,您可以timeline.json在浏览器下打开chrome://tracing并查看时间

在此输入图像描述

您可以看到它并行运行两个1024x1024矩阵乘法运算,每个运算大约需要85ms,最低可达25 M ops /秒,相当于2年前macbook的单核性能.

另一方面,你可以在6个不同的CPU设备上运行6个这样的矩阵乘法,你会看到类似的东西.

在此输入图像描述

我只有4个物理内核,你看到其中2个操作需要2倍的时间.尽管它们在逻辑cpu设备上处于活动状态,但在前100ms内有任何可用的物理内核,因此它们没有取得任何进展.