如何用SSE4.2和AVX指令编译Tensorflow?

2024-05-20 22:18:39 发布

您现在位置:Python中文网/ 问答频道 /正文

这是运行脚本检查Tensorflow是否工作时收到的消息:

I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcublas.so.8.0 locally
I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcudnn.so.5 locally
I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcufft.so.8.0 locally
I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcuda.so.1 locally
I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcurand.so.8.0 locally
W tensorflow/core/platform/cpu_feature_guard.cc:95] The TensorFlow library wasn't compiled to use SSE4.2 instructions, but these are available on your machine and could speed up CPU computations.
W tensorflow/core/platform/cpu_feature_guard.cc:95] The TensorFlow library wasn't compiled to use AVX instructions, but these are available on your machine and could speed up CPU computations.
I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:910] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero

我注意到上面提到了SSE4.2和AVX

  1. 什么是SSE4.2和AVX?
  2. 这些SSE4.2和AVX如何改进Tensorflow任务的CPU计算。
  3. 如何使用这两个库来编译Tensorflow?

Tags: streamtensorflowlibraryloadercpucudabutcc
3条回答

我们先来解释一下为什么您会首先看到这些警告


很可能您没有从源代码安装TF,而是使用了类似pip install tensorflow的内容。这意味着您安装了未针对您的体系结构进行优化的预构建(由其他人)二进制文件。这些警告确切地告诉您:您的体系结构中有可用的东西,但它不会被使用,因为二进制文件不是用它编译的。这是来自documentation的部分。

TensorFlow checks on startup whether it has been compiled with the optimizations available on the CPU. If the optimizations are not included, TensorFlow will emit warnings, e.g. AVX, AVX2, and FMA instructions not included.

好在很可能你只是想学习/试验TF,这样一切都会正常工作,你不必担心它


什么是SSE4.2和AVX?

维基百科对SSE4.2AVX有很好的解释。这些知识不要求擅长机器学习。您可以将它们看作是一组额外的instructions,计算机可以对一条指令使用多个数据点来执行自然并行的操作(例如添加两个数组)。

SSE和AVX都是SIMD(单指令,多数据)抽象思想的实现,即

a class of parallel computers in Flynn's taxonomy. It describes computers with multiple processing elements that perform the same operation on multiple data points simultaneously. Thus, such machines exploit data level parallelism, but not concurrency: there are simultaneous (parallel) computations, but only a single process (instruction) at a given moment

这足以回答你的下一个问题。


这些SSE4.2和AVX如何改进TF任务的CPU计算

它们允许更有效地计算各种向量(矩阵/张量)运算。您可以在these slides中阅读更多内容


如何使用这两个库编译Tensorflow?

您需要有一个二进制文件,它是为了利用这些指令而编译的。最简单的方法是compile it yourself。正如Mike和Yaroslav建议的那样,您可以使用下面的bazel命令

bazel build -c opt --copt=-mavx --copt=-mavx2 --copt=-mfma --copt=-mfpmath=both --copt=-msse4.2 --config=cuda -k //tensorflow/tools/pip_package:build_pip_package

让我先回答您的第三个问题:

如果要在conda env中运行自编译版本,可以。这些是我运行的一般说明,以使tensorflow安装在我的系统上,并附带附加说明。注意:这个版本是为运行Ubuntu16.04LTS的AMDA10-7850版本(检查你的CPU是否支持什么指令…可能有所不同)。我在conda env中使用Python 3.5。本文将介绍tensorflow源代码安装页面和上面提供的答案。

git clone https://github.com/tensorflow/tensorflow 
# Install Bazel
# https://bazel.build/versions/master/docs/install.html
sudo apt-get install python3-numpy python3-dev python3-pip python3-wheel
# Create your virtual env with conda.
source activate YOUR_ENV
pip install six numpy wheel, packaging, appdir
# Follow the configure instructions at:
# https://www.tensorflow.org/install/install_sources
# Build your build like below. Note: Check what instructions your CPU 
# support. Also. If resources are limited consider adding the following 
# tag --local_resources 2048,.5,1.0 . This will limit how much ram many
# local resources are used but will increase time to compile.
bazel build -c opt --copt=-mavx --copt=-msse4.1 --copt=-msse4.2  -k //tensorflow/tools/pip_package:build_pip_package
# Create the wheel like so:
bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
# Inside your conda env:
pip install /tmp/tensorflow_pkg/NAME_OF_WHEEL.whl
# Then install the rest of your stack
pip install keras jupyter etc. etc.

关于第二个问题:

在我看来,一个经过优化的自编版本是非常值得的。在我的特殊设置中,过去需要560-600秒的计算现在只需要大约300秒!虽然确切的数字会有所不同,但我认为您可以预期在您的特定设置上的速度通常会提高35-50%。

最后一个问题:

上面已经提供了很多答案。综上所述:AVXSSE4.1, SSE4.2,MFA是X86 cpu上不同类型的扩展指令集。许多包含处理矩阵或向量运算的优化指令。

我将强调我自己的误解,希望能为您节省一些时间:并不是说SSE4.2是取代SSE4.1的指令的新版本。SSE4=SSE4.1(一组47条指令)+SSE4.2(一组7条指令)。

在tensorflow编译的上下文中,如果您的计算机支持AVX2和AVX,以及SSE4.1和SSE4.2,那么您应该为所有人放置这些优化标志。不要像我这样做,只要去SSE4.2认为它是新的,应该超越SSE4.1。那显然是错的!我不得不重新编译,因为那花了我整整40分钟。

我刚刚遇到了同样的问题,Yaroslav Bulatov的建议似乎不包括SSE4.2支持,添加--copt=-msse4.2就足够了。最后,我成功地用

bazel build -c opt --copt=-mavx --copt=-mavx2 --copt=-mfma --copt=-mfpmath=both --copt=-msse4.2 --config=cuda -k //tensorflow/tools/pip_package:build_pip_package

没有任何警告或错误。

任何系统的最佳选择可能是:

bazel build -c opt --copt=-march=native --copt=-mfpmath=both --config=cuda -k //tensorflow/tools/pip_package:build_pip_package

更新:the build scripts may be eating ^{},可能是因为它包含一个=

-mfpmath=both只适用于gcc,不适用于clang。-mfpmath=sse可能同样好,如果不是更好的话,也是x86-64的默认值。32位构建默认值为-mfpmath=387,因此更改该值将有助于32位。(但是,如果您想要高性能的数字处理,您应该构建64位二进制文件。)

我不确定TensorFlow对于-O2-O3的默认值是什么。gcc -O3支持完全优化,包括自动矢量化,但有时会使代码变慢。


<>这是什么:^{} for ^{}直接将一个选项传递给GCC来编译C和C++文件(但不链接,因此需要跨文件链接时间优化的不同选项)

x86-64 gcc默认只使用SSE2或更早的SIMD指令,因此可以在anyx86-64系统上运行二进制文件。(见https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html)。那不是你想要的。您希望生成一个二进制文件,它可以利用您的CPU可以运行的所有指令,因为您只在构建它的系统上运行这个二进制文件。

-march=native启用您的CPU支持的所有选项,因此它使-mavx512f -mavx2 -mavx -mfma -msse4.2冗余。(而且,-mavx2已经启用了-mavx-msse4.2,因此Yaroslav的命令应该是正确的)。另外,如果您使用的CPU不支持这些选项之一(如FMA),那么使用-mfma将生成一个二进制文件,该二进制文件会因非法指令而出错。

TensorFlow's ^{} defaults to enabling ^{},因此使用它应该避免手动指定编译器选项。

-march=native启用-mtune=native,因此it optimizes for your CPU对于诸如哪一个AVX指令序列最适合未对齐的加载之类的事情。

所有这些都适用于gcc、clang或ICC。(对于ICC,可以使用-xHOST,而不是-march=native。)

相关问题 更多 >