Python代碼運行不夠流暢?看大神如何多角度優化!
更多深度文章,請關注:https://yq.aliyun.com/cloud
這是“Python代碼性能優化”係列中的第一篇文章——環境設置。通過每個帖子,我將介紹一些Python代碼的工具和剖析器,以及它們中的每一個如何幫助您更好地在前端(Python腳本)和/或後端(Python解釋器)中找到突破點。
配置:
在進行基本測試和分析之前,首先需要一個適當的環境。這意味著必須為此任務配置機器和操作係統。
一般來說,我的機器有以下規格:
- 處理器:Intel(R)Xeon(R)CPU E5-2699 v3 @ 2.30GHz
- 內存:32GB
- 操作係統:Ubuntu 16.04 LTS
- 內核:4.4.0-75通用
我們的目標是得到具有可重複的結果,從而確保我們的數據不受其他後台進程、操作係統配置或任何其他硬件性能帶來的影響。
我們從配置我們用於分析的機器開始。
硬件功能:
首先,禁用任何硬件性能功能。這意味著從BIOS / UEFI禁用Intel Turbo Boost和超線程。
正如官方所述,Turbo Boost是一種技術,如果處理器內核運行在低於功率、電流和溫度規格限製的情況下,自動允許處理器內核的運行速度高於額定工作頻率。另一方麵,超線程是“更有效地使用處理器資源的技術,可以使多個線程在每個核心上運行”,如這裏所述。
我們花了錢在工具上,而且我們真的想讓它們發揮它們的作用。那麼為什麼在分析/基準測試時能夠啟用它們呢?因為我們沒有得到可靠和可重複的結果,這轉化為運行變化。讓我們在一個小例子中看到這一點,叫做primes.py。
該代碼也可在GitHub上找到。作為依賴分析,您將需要運行:
pip install statistics
讓我們在啟用了Turbo Boost並超線程的係統中運行它:
python primes.py
Benchmark duration:1.0644240379333496seconds
Mean duration:0.2128755569458008seconds
Standard deviation:0.032928838418120374(15.468585914964498 %)
現在,在同一個係統上,但是禁用Turbo Boost和超線程:
python primes.py
Benchmark duration:1.2374498844146729seconds
Mean duration:0.12374367713928222seconds
Standard deviation:0.000684464852339824(0.553131172568 %)
觀察第一種情況下的標準差--15%。相反,在第二種情況下,變化減小到約0.6%。這難道不是優化產生的巨大價值嗎?
CPU設置:
禁用一些CPU的功能,能夠省電並能使用固定的CPU頻率。實現這個功能可以通過將Linux調節器從更改intel_pstate
為 acpi_cpufreq
。
該intel_pstate
驅動程序使用Intel Core(Sandy Bridge和更新的)處理器的內部調節器實現縮放驅動程序。該acpi_cpufreq
驅動器利用ACPI處理器性能狀態。我們先來看看吧!
$ cpupower frequency-info
analyzing CPU 0:
driver: intel_pstate
CPUs which run at the same hardware frequency: 0
CPUs which need to have their frequency coordinated by software: 0
maximum transition latency: 0.97 ms.
hardware limits: 1.20 GHz - 3.60 GHz
available cpufreq governors: performance, powersave
current policy: frequency should be within 1.20 GHz and 3.60 GHz.
The governor "powersave" may decide which speed to use within this range.
current CPU frequency is 1.20 GHz.
boost state support:
Supported: yes
Active: yes
您會看到使用調節器設置為powersave,CPU頻率會在1.20 GHz和3.60 GHz之間。這對您的個人電腦或其他日常使用是有好處的,但在做基準測試時會影響到結果。
調節器還有其他什麼功能?如果你瀏覽文檔,你會看到以下內容:
- performance - 以最高頻率運行CPU。
- powersave - 以最低頻率運行CPU。
- userspace - 以用戶指定的頻率運行CPU。
- ondemand - 根據當前負載動態縮放頻率。跳轉到最高頻率,然後可能隨著空閑時間的增加而退回。
- conservative - 根據當前負載動態縮放頻率。比頻率更頻繁地擴大頻率。
我們想要使用的是性能調節器,並將頻率設置在CPU支持的最大值。比如說是這樣的結果:
$ cpupower frequency-info
analyzing CPU 0:
driver: acpi-cpufreq
CPUs which run at the same hardware frequency: 0
CPUs which need to have their frequency coordinated by software: 0
maximum transition latency: 10.0 us.
hardware limits: 1.20 GHz - 2.30 GHz
available frequency steps: 2.30 GHz, 2.20 GHz, 2.10 GHz, 2.00 GHz, 1.90 GHz, 1.80 GHz, 1.70 GHz, 1.60 GHz, 1.50 GHz, 1.40 GHz, 1.30 GHz, 1.20 GHz
available cpufreq governors: conservative, ondemand, userspace, powersave, performance
current policy: frequency should be within 2.30 GHz and 2.30 GHz.
The governor "performance" may decide which speed to use
within this range.
current CPU frequency is 2.30 GHz.
cpufreq stats: 2.30 GHz:100.00%, 2.20 GHz:0.00%, 2.10 GHz:0.00%, 2.00 GHz:0.00%, 1.90 GHz:0.00%, 1.80 GHz:0.00%, 1.70 GHz:0.00%, 1.60 GHz:0.00%, 1.50 GHz:0.00%, 1.40 GHz:0.00%, 1.30 GHz:0.00%, 1.20 GHz:0.00% (174)
boost state support:
Supported: no
Active: no
現在你要使用 performance 調節器,固定頻率為2.3 GHz。該值是可以在Xeon E5-2699 v3上使用的最大的可能,沒有Turbo Boost。要設置所有內容,請以管理權限運行以下命令:
cpupower frequency-set -g performance
cpupower frequency-set --min 2300000 --max 2300000
如果沒有cpupower
,請使用以下命令安裝:
sudo apt-get install linux-tools-common linux-header-`uname -r` -y
調節器對CPU的使用有很大的影響。默認情況下,調速器設置為自動縮放頻率以降低功耗。我們不希望在我們的係統上,我們繼續從GRUB禁用它。隻需編輯/boot/grub/grub.cfg
(但是如果您在內核升級時操作要小心,這將會消失)或者在其中創建一個新的內核條目 /etc/grub.d/40_custom
。我們的引導行必須包含以下標誌:intel_pstate=disable
,如下所示:
linux/boot/vmlinuz-4.4.0-78-generic.efi.signed root=UUID=86097ec1-3fa4-4d00-97c7-3bf91787be83 ro intel_pstate=disable quiet splash $vt_handoff
ASLR設置(地址空間布局隨機器):
這個設置是有爭議的,你可以在Victor Stinner的帖子中看到。當我第一次建議在執行基準測試時禁用ASLR,這是在進一步改進對CPython中存在的Profile Guided Optimizations的支持的背景下。
什麼導致我說這是個事實,在上麵提到的特定硬件上,禁用ASLR,運行primes.py,標準差變化到0.4%!
另一方麵,在我的個人計算機(擁有Intel Core i7 4710MQ)上進行測試,使得禁用ASLR導致出現了Victor所提出的相同問題。
由於它似乎不是普遍可用的結論,而是在很大程度上取決於硬件/軟件配置,所以最好的方法是讓它啟用並測試,禁用它並重新測試,然後比較結果。
在我的機器上,我通過添加以下內容在全球禁用/etc/sysctl.conf
。
申請使用sudo sysctl -p
。
kernel.randomize_va_space = 0
如果要在運行時禁用它:
sudo bash -c 'echo 0 >| /proc/sys/kernel/randomize_va_space'
如果要啟用它:
sudo bash -c 'echo 2 >| /proc/sys/kernel/randomize_va_space'
本文由北郵@愛可可-愛生活老師推薦,
文章原標題《》,
作者:pythonrinf 譯者:袁虎 審閱:
文章為簡譯,更為詳細的內容,請查看原文
最後更新:2017-07-12 22:05:20