如何使Python3解释器更快或尽可能快?

Dan*_*ter 3 optimization gcc cpython clang compiler-optimization

正如标题所说,如何制作执行python程序的python3解释器;使用 www.python.org 上提供的普通 CPython 版本可以更快甚至最快​​;在任何 Linux 发行版中?

有没有办法让它比默认的“--enable-optimizations”编译器标志更快?

使用哪个编译器来实现目标?

有哪些支持性基准来证实编译器选择的断言?

Dan*_*ter 8

我想我找到了一种方法,但它只是让它比我的基准测试稍微快一些。

我通过执行以下操作来做到这一点:

  1. 将 PGO 的分析扩展到 python3 源附带的所有 425 个回归测试。配置“--enable-optimizations”仅运行 Python3 源附带的 425 回归测试的一小部分。
  2. 通过“--with-lto”配置选项添加带有 LTO 的 CFLAGS="-march=native -O3 -pipe"
  3. 将“-fprofile-update=prefer-atomic”添加到分析阶段
  4. 将“-fprofile-partial-training”添加到最终反馈定向优化 (FDO) 阶段。

上面的事情该怎么做,会有什么后果?

首先,结果...

正如他们所说,图片描绘了一千个单词!

  • 红色蟒蛇已完成上述 1-4 点。
  • 而绿色 python 只有点 2,其库存“--enable-optimizations”配置执行有限的 PGO 子集。

越低越好。所以你可以看到大部分胜利都属于红色蟒蛇,而绿色蟒蛇则有一些胜利。

Pyperformance 用于基准测试,重点关注现实世界的基准测试,而不是合成基准测试,并尽可能使用整个应用程序。

https://pyperformance.readthedocs.io/index.html

它是使用 pyperfplot 绘制的。

https://github.com/stefantalpalaru/pyperfplot

这一努力激起了我的兴趣,所以我又做了几个基准测试,花了一整天的时间...... 在此输入图像描述

  • 红色和黄色蟒蛇与上图中的红色和绿色蟒蛇相同。
  • Green python 是来自 Ubuntu 存储库的 Python3.9,由他们使用 gcc9.3 编译。
  • 浅蓝色 python 是 Clang12,具有上述第 2 点,具有库存“--enable-optimizations”配置,该配置执行有限的 PGO 子集。它是基准测试中表现最差的!真正令人惊讶的是,我开始这项工作时认为 Clang-12 会胜出,因为 Linux 现在完全支持 LTO,并且 Clang-12 在过去几个月的许多 Phoronix 基准测试文章中占据了第一名。
  • 深蓝色是来自存储库的默认 Ubuntu Python3.8。添加到这里只是为了显示从 3.8 到 3.9 是否有进展,并与我的自定义版本进行比较。

那么以上4点该怎么做,会有什么后果呢?

  1. 获取你想要构建的python3版本,我得到了3.9.6...
wget https://www.python.org/ftp/python/3.9.6/Python-3.9.6.tar.xz
Run Code Online (Sandbox Code Playgroud)
  1. 解压...
tar -xf ./Python-3.9.6.tar.xz
Run Code Online (Sandbox Code Playgroud)
  1. 进入该目录并进行配置。
cd ./Python-3.9.6
Run Code Online (Sandbox Code Playgroud)

对于海湾合作委员会


time CFLAGS="-march=native -O3 -pipe" ./configure --enable-optimizations --with-lto
Run Code Online (Sandbox Code Playgroud)

为铿锵

time CC="clang" CFLAGS="-march=native -O3 -pipe -Wno-unused-value -Wno-empty-body -Qunused-arguments -Wno-parentheses-equality" ./configure --enable-optimizations --with-lto
Run Code Online (Sandbox Code Playgroud)

clang 的额外选项只是遵循 python 开发人员的官方建议... https://devguide.python.org/setup/#clang

  1. 此时,您将开始传统的构建/编译。然而,我们希望在分析和最终发布构建期间使用额外选项进一步自定义构建方式。
nano Makefile
Run Code Online (Sandbox Code Playgroud)

搜索“PGO_PROF_GEN_FLAG”(ctrl+w)并在空格“-fprofile-update=prefer-atomic”后附加(不带引号)。它应该看起来像......

PGO_PROF_GEN_FLAG=-fprofile-generate -fprofile-update=prefer-atomic
Run Code Online (Sandbox Code Playgroud)
  1. 下面的下一行应为“PGO_PROF_USE_FLAG”;它会影响最终版本构建/编译在末尾的空格后附加“-fprofile-partial-training”(不带引号)。它应该看起来像......
PGO_PROF_USE_FLAG=-fprofile-use -fprofile-correction -fprofile-partial-training
Run Code Online (Sandbox Code Playgroud)

请注意 ,这一点仅与 gcc 兼容。在撰写本文时,“-fprofile-partial-training”不适用于clang-12。如果没有此设置,gcc 将“优化大小”不属于分析的代码路径。启用此设置将使 gcc 优化未分析的代码路径,积极“优化速度”,这可以带来更好的性能,但代价是更大的代码大小。
请参阅此处: https: //gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

  1. 最后,我们扩展了回归测试列表,从库存子集运行到完整的测试集。仍在“nano Makefile”中搜索“PROFILE_TASK= -m test --pgo”并将其替换为:
PROFILE_TASK=   -m test --pgo-extended
Run Code Online (Sandbox Code Playgroud)
  1. 现在您可以开始构建了。但请注意,启用全套测试进行分析将大大增加完成构建 Python3 所需的时间。
time make -j$(( $(nproc) + 1 ))
Run Code Online (Sandbox Code Playgroud)

上面命令中的 -j 公式只是计算出您拥有的 cpu 数量,并为构建/编译/链接的多重处理添加 1 以加快速度。

不幸的是,回归测试将按顺序执行,没有简单的方法可以切换到运行测试的并发方式。它将运行 425 个测试来分析所有这些!

在我的 i7-3770 上花了这么长时间......

real    49m26.882s
user    55m1.160s
sys 2m1.106s

Run Code Online (Sandbox Code Playgroud)

但我确实有一些其他程序和应用程序以及一个虚拟机同时运行。

  1. 完成后,“altinstall”,这样你就不会弄乱发行版附带的默认 python3,从而导致问题。
sudo make altinstall
Run Code Online (Sandbox Code Playgroud)
  1. 如果您有多个自定义构建的 python 版本,请使用 update-alternatives 来管理它们。
sudo update-alternatives --verbose --install /usr/local/bin/python3 python3 /usr/local/bin/python3.7 374 --slave /usr/local/bin/python3-config python3-config /usr/local/bin/python3.7-config
sudo update-alternatives --verbose --install /usr/local/bin/python3 python3 /usr/local/bin/python3.8 382 --slave /usr/local/bin/python3-config python3-config /usr/local/bin/python3.8-config
sudo update-alternatives --verbose --install /usr/local/bin/python3 python3 /usr/local/bin/python3.9 396 --slave /usr/local/bin/python3-config python3-config /usr/local/bin/python3.9-config
Run Code Online (Sandbox Code Playgroud)

使用以下命令配置默认的“python3”

sudo update-alternatives --config python3
Run Code Online (Sandbox Code Playgroud)

这是我的...

There are 4 choices for the alternative python3 (providing /usr/local/bin/python3).

  Selection    Path                      Priority   Status
------------------------------------------------------------
* 0            /usr/local/bin/python3.9   396       auto mode
  1            /usr/bin/pypy3             369       manual mode
  2            /usr/local/bin/python3.7   374       manual mode
  3            /usr/local/bin/python3.8   382       manual mode
  4            /usr/local/bin/python3.9   396       manual mode

Press <enter> to keep the current choice[*], or type selection number:
Run Code Online (Sandbox Code Playgroud)

最后,需要注意的是“/usr/bin”中的任何 python3 都属于您的 Linux 发行版。尽量不要搞乱它,因为它可能会在以后把事情搞砸。您的所有替代安装都将到达“/usr/local/bin”。

一些结论...

  • Clang,一个很棒的编译器和项目,对 python3 来说是不利的,至少在我的设置中是这样。也许如果他们的开发人员正在阅读本文,他们可以采取一些措施。
  • GCC 规则 Python3,我没有 Intel 的编译器(ICC?)所以不知道,但我听说它在用于构建 python3 时甚至更好。
  • 上述和概述的调整使我的默认 python3 总体上更快、更敏捷,但是构建它花了很多时间!我认为这是值得的。

更新: Python 3.10.0 与 ubuntu 20.04 股票 python 3.8.10

Python 3.10.0 具有完整的 PGO、部分训练、Prefer-atomic、march=native (zen3 R7-5800X)、O3 优化
明确获胜 --> 33
Python 3.8.10 来自存储库的 Ubuntu 库存
明确获胜 --> 22

然而,从图表中您可以看到,Ubuntu 存储库中的 3.10 版本输给了 3.8.10 版本,其中一些幅度相当大。

Python3.10-Zen3Native-PGO-PartialTraining-PreferAtomic.VS.Stock-Python3.8.10