【问题标题】:tf.matmul() at 35% slower then np.dot() when calculating on the CPU在 CPU 上计算时,tf.matmul() 比 np.dot() 慢 35%
【发布时间】:2017-09-13 13:50:44
【问题描述】:

我从源文件编译了 tensorflow 1.3,对产品的性能感到不快。考虑到社区的 cmets 在 CPU 上进行计算时,已经设法将 numpy 相对于 tensorflow 的优势从 45% 降低到 35%。但是,差别还是很大的。基准代码如下:

#! /usr/bin/env python3

import sys
import time
import numpy as np
import tensorflow as tf

print('Python', sys.version)
print('TensorFlow', tf.__version__)

gDType = np.float64
size = 8192

# Numpy calculation
rand_array = np.random.uniform(0, 1, (size, size))
timer0 = time.time()  
res = np.dot(np.dot(rand_array, rand_array), rand_array)
print("numpy multiply: %f" % (time.time() - timer0))


# TensorFlow calculation
x = tf.Variable( tf.random_uniform(shape=(size, size), minval=0, maxval=1, dtype=gDType), dtype=gDType, name='x')
x3 = tf.matmul(tf.matmul(x, x), x)

# Avoid optimizing away redundant nodes
config = tf.ConfigProto(graph_options=tf.GraphOptions(optimizer_options=tf.OptimizerOptions(opt_level=tf.OptimizerOptions.L0)))
sess = tf.Session(config=config)
# sess = tf.Session()  
sess.run(tf.global_variables_initializer())

# Exclude delays caused by initialization of the graph
timer0 = time.time()
sess.run(x3.op)
print("tensorflow multiply 1 pass: %f" % (time.time() - timer0))


timer0 = time.time()
sess.run(x3.op)
print("tensorflow multiply 2 pass: %f" % (time.time() - timer0))

这是脚本的输出:

$ ./matmul_benchmark.py 
Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609]
TensorFlow 1.3.0
numpy multiply: 37.464786
tensorflow multiply 1 pass: 61.245776
tensorflow multiply 2 pass: 49.944690

进程中的脚本消耗 4 GB 的 RAM,您可能希望将 size 变量减小到 4096。

对比显示 numpy 的优越性提高了 35%(50 秒/37 秒)。

请告诉我,这次测试有什么错误吗?

PS。我的 CPU Sandy-bridge 标志:

$ lscpu | grep Flags
Flags:                 fpu vme de pse tsc msr pae mce cx8 apic sep mtrr
pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss ht syscall nx
rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology tsc_reliable
nonstop_tsc aperfmperf pni pclmulqdq ssse3 cx16 **sse4_1 sse4_2** popcnt aes
xsave **avx** hypervisor lahf_lm epb xsaveopt dtherm ida arat pln pts

【问题讨论】:

  • 天啊,我希望如此。点积产生一个数,矩阵相乘产生 N*M。
  • @HansPassant,这是不正确的。阅读docs.scipy.org/doc/numpy/reference/generated/numpy.dot.html。摘录:对于二维数组,它相当于矩阵乘法,对于一维数组,它相当于向量的内积(没有复共轭)。对于 N 维,它是 a 的最后一个轴和 b 的倒数第二个轴的和积:dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])

标签: performance tensorflow


【解决方案1】:

英特尔通过使用适用于深度神经网络的数学内核库,为 TensorFlow 为 Xeon 和 Xeon Phi 添加了优化。编译 tensorflow 1.3+ 时,应考虑在编译期间添加--config=mkl 选项。它只支持 Linux 操作系统。不确定它将为您进行基准测试提供多少加速。

一些 numpy 发行版已经包含 MKL 支持。例如 Anaconda 2.5 及更高版本,MKL 默认可用。

【讨论】:

  • 我建议看一下article的摘录:“当指定了bazel选项“--config=opt”时,请指定要在编译期间使用的优化标志[默认为-march=native]这个问题是指稍后你将使用 bazel 构建 pip 包的阶段。我们建议接受默认值 (-march=native),这将针对本地计算机的 CPU 类型优化生成的代码。 - 我相信指定的优化已启用。感谢您的帮助。
  • 你是对的,选项 --config=mkl 是单独定义的。重新编译后TF和NP的性能是一样的。
【解决方案2】:
  1. 第一个 session.run 需要更长的时间,因为它有初始化调用
  2. 您是否使用优化的 numpy (np.__config__.get_info())?您的 TensorFlow 是否经过所有优化编译? (build -c opt --config=opt)

  3. Numpy 和 tensorflow 分别管理内存,session.run 的默认行为是将结果复制到 numpy 运行时。您可以将所有数据保留在 TF 运行时中以降低开销。

这是一个避免常见陷阱的版本(减少了将结果不必要地复制回 numpy 的开销)--Testing GPU with tensorflow matrix multiplication

在最佳情况下,我在 GPU 上获得 11 T ops/sec,在 Xeon V3 上获得 1.1 T ops/sec(与 conda numpy 类似的 0.5 T ops/sec)

【讨论】:

  • 谢谢你,我很欣赏你的文章。 numpy 相对于 tensorflow 的优势从 45% 降低到 35%。但是,差别还是很大的。我已将修补程序包含在主帖中。是否有可能改善这种情况?
  • 在 np.float32 上用 np.float64 更改变量 gDType 后,脚本的执行时间减少到 19 秒。 (260%)。 Tensorflow 是否不适用于 np.float64?
  • 当我在我的机器(Xeon E5-2630 v3 @ 2.40GHz)上运行 matmul_bench.py​​ 时,TF 需要 1 秒,numpy 需要 3.2 秒,所以 TF 快了 3 倍 -- @987654322 @
  • 能不能把类型改成 np.float64 再重复比较一下?
  • 那么 numpy 是 5.7 秒,而 TensorFlow 是 2.5 秒。我猜我的 numpy 分布没有得到适当的优化。如果您使用 MKL 链接的 TensorFlow 与 MKL 链接的 numpy,我期望相同的性能,因为它们将为 matmul 调用相同的函数
猜你喜欢
  • 2017-04-05
  • 1970-01-01
  • 2017-02-27
  • 1970-01-01
  • 2014-10-07
  • 2019-11-06
  • 2015-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多