《PHP學習:使用Huagepage和PGO來提升PHP7的執(zhí)行性能》要點:
本文介紹了PHP學習:使用Huagepage和PGO來提升PHP7的執(zhí)行性能,希望對您有用。如果有疑問,可以聯系我們。
PHP學習Hugepage
PHP7剛剛發(fā)布了RC4, 包括一些bug修復和一個我們最新的性能提升成果, 那就是”HugePageFy PHP TEXT segment”, 通過啟用這個特性,PHP7會把自身的TEXT段(執(zhí)行體)”挪“到Huagepage上,之前的測試,我們能穩(wěn)定的在Wordpress上看到2%~3%的QPS提升.
PHP學習關于Hugepage是啥,簡單的說下就是默認的內存是以4KB分頁的,而虛擬地址和內存地址是需要轉換的, 而這個轉換是要查表的,CPU為了加速這個查表過程都會內建TLB(Translation Lookaside Buffer), 顯而易見如果虛擬頁越小,表里的條目數也就越多,而TLB大小是有限的,條目數越多TLB的Cache Miss也就會越高, 所以如果我們能啟用大內存頁就能間接降低這個TLB Cache Miss,至于詳細的介紹,Google一搜一大堆我就不贅述了,這里主要說明下如何啟用這個新特性, 從而帶來明顯的性能提升.
PHP學習新的Kernel啟用Hugepage已經變得非常容易了,以我的開發(fā)虛擬機為例(Ubuntu Server 14.04,Kernel 3.13.0-45), 如果我們查看內存信息:
PHP學習
$ cat /proc/meminfo | grep Huge
PHP學習
AnonHugePages: 444416 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
PHP學習可見一個Hugepage的size是2MB, 而當前并沒有啟用HugePages. 現在讓我們先編譯PHP RC4, 記得一定不要加: Cdisable-huge-code-pages (這個新特性是默認啟用的, 你加了這個就關了)
PHP學習然后配置opcache, 從PHP5.5開始Opcache已經是默認啟用編譯的,但是是編譯動態(tài)庫的, 所以我們還是要在php.ini中配置加載下.
PHP學習
zend_extension=opcache.so
PHP學習這個新特性是做在Opcache里的,所以也要通過Opcache啟用這個特性(通過設置opcache.huge_code_pages=1), 具體的配置:
PHP學習
opcache.huge_code_pages=1
PHP學習現在讓我們配置OS, 分配一些Hugepages:
PHP學習
$ sudo sysctl vm.nr_hugepages=128
vm.nr_hugepages = 128
PHP學習現在讓我們再次檢查內存信息:
PHP學習
$ cat /proc/meminfo | grep Huge
PHP學習
AnonHugePages: 444416 kB
HugePages_Total: 128
HugePages_Free: 128
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
PHP學習可以看到我們分配的128個Hugepages已經就緒了, 然后我們來啟動php-fpm:
PHP學習
$ /home/huixinchen/local/php7/sbin/php-fpm
PHP學習
[01-Oct-2015 09:33:27] NOTICE: [pool www] 'user' directive is ignored when FPM is not running as root
[01-Oct-2015 09:33:27] NOTICE: [pool www] 'group' directive is ignored when FPM is not running as root
PHP學習現在, 再次檢查內存信息:
PHP學習
$ cat /proc/meminfo | grep Huge
PHP學習
AnonHugePages: 411648 kB
HugePages_Total: 128
HugePages_Free: 113
HugePages_Rsvd: 27
HugePages_Surp: 0
Hugepagesize: 2048 kB
PHP學習說到這里,如果Hugepages可用, 其實Opcache也會用Hugepages來存儲opcodes緩存, 所以為了驗證opcache.huge_code_pages確實生效, 我們不妨關閉opcache.huge_code_pages, 然后再啟動一次后看內存信息:
PHP學習
$ cat /proc/meminfo | grep Huge
PHP學習
AnonHugePages: 436224 kB
HugePages_Total: 128
HugePages_Free: 117
HugePages_Rsvd: 27
HugePages_Surp: 0
Hugepagesize: 2048 kB
PHP學習可見開啟了huge_code_pages以后, fpm啟動后多用了4個pages, 現在我們檢查下php-fpm的text大?。?/p>
PHP學習
$ size /home/huixinchen/local/php7/sbin/php-fpm
PHP學習
text data bss dec hex filename
10114565 695200 131528 10941293 a6f36d /home/huixinchen/local/php7/sbin/php-fpm
PHP學習可見text段有10114565個字節(jié)大小, 總共需要占用4.8個左右的2M的pages, 考慮到對齊以后(尾部不足2M Page部分不挪動), 申請4個pages, 正好和我們看到的相符.
PHP學習說明配置成功! Enjoy :)
PHP學習但是有言在先, 啟用此特性以后, 會造成一個問題就是你如果嘗試通過Perf report/anno 去profiling的時候, 會發(fā)現符號丟失(valgrind, gdb不受影響), 這個主要原因是Perf的設計采用監(jiān)聽了mmap,然跋文錄地址范圍, 做IP到符號的轉換, 但是目前HugeTLB只支持MAP_ANON, 所以導致Perf認為這部分地址沒有符號信息,希望以后版本的Kernel可以修復這個限制吧..
PHP學習GCC PGO
PGO正如名字所說(Profile Guided Optimization 有興趣的可以Google), 他需要用一些用例來獲得反饋, 也就是說這個優(yōu)化是需要和一個特定的場景綁定的.
PHP學習你對一個場景的優(yōu)化, 也許在另外一個場景就事與愿違了. 它不是一個通用的優(yōu)化. 所以我們不能簡單的就包括這些優(yōu)化, 也無法直接發(fā)布PGO編譯后的PHP7.
PHP學習當然, 我們正在嘗試從PGO找出一些共性的優(yōu)化, 然后手工Apply到PHP7上去, 但這個很明顯不能做到針對一個場景的特別優(yōu)化所能達到的效果, 所以我決定寫這篇文章簡單介紹下怎么使用PGO來編譯PHP7, 讓你編譯的PHP7能特別的讓你本身的獨立的應用變得更快.
PHP學習首先, 要決定的就是拿什么場景去Feedback GCC, 我們一般都會選擇: 在你要優(yōu)化的場景中: 拜訪量最大的, 耗時最多的, 資源消耗最重的一個頁面.
PHP學習拿Wordpress為例, 我們選擇Wordpress的首頁(因為首頁往往是拜訪量最大的).
PHP學習我們以我的機器為例:
PHP學習?????? Intel(R) Xeon(R) CPU?????????? X5687? @ 3.60GHz X 16(超線程),
?????? 48G Memory
php-fpm 采用固定32個worker, opcache采用默認的配置(一定要記得加載opcache)
PHP學習以wordpress 4.1為優(yōu)化場景..
PHP學習首先我們來測試下目前WP在PHP7的性能(ab -n 10000 -c 100):
PHP學習
$ ab -n 10000 -c 100 http://inf-dev-maybach.weibo.com:8000/wordpress/
PHP學習
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking inf-dev-maybach.weibo.com (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests
Server Software: nginx/1.7.12
Server Hostname: inf-dev-maybach.weibo.com
Server Port: 8000
Document Path: /wordpress/
Document Length: 9048 bytes
Concurrency Level: 100
Time taken for tests: 8.957 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 92860000 bytes
HTML transferred: 90480000 bytes
Requests per second: 1116.48 [#/sec] (mean)
Time per request: 89.567 [ms] (mean)
Time per request: 0.896 [ms] (mean, across all concurrent requests)
Transfer rate: 10124.65 [Kbytes/sec] received
PHP學習可見Wordpress 4.1 目前在這個機器上, 首頁的QPS可以到1116.48. 也就是每秒鐘可以處理這么多個對首頁的哀求,
PHP學習現在, 讓我們開始教GCC, 讓他編譯出跑Wordpress4.1更快的PHP7來, 首先要求GCC 4.0以上的版本, 不過我建議大家使用GCC-4.8以上的版本(現在都GCC-5.1了).
PHP學習第一步, 自然是下載PHP7的源代碼了, 然后做./configure. 這些都沒什么區(qū)別
PHP學習接下來就是有區(qū)別的地方了, 我們要首先第一遍編譯PHP7, 讓它生成會產生profile數據的可執(zhí)行文件:
PHP學習
$ make prof-gen
PHP學習注意, 我們用到了prof-gen參數(這個是PHP7的Makefile特有的, 不要嘗試在其他項目上也這么搞哈 :) )
PHP學習然后, 讓我們開始訓練GCC:
PHP學習
$ sapi/cgi/php-cgi -T 100 /home/huixinchen/local/www/htdocs/wordpress/index.php >/dev/null
PHP學習也就是讓php-cgi跑100遍wordpress的首頁, 從而生成一些在這個過程中的profile信息.
PHP學習然后, 我們開始第二次編譯PHP7.
PHP學習
$ make prof-clean
$ make prof-use && make install
PHP學習好的, 就這么簡單, PGO編譯完成了, 現在我們看看PGO編譯以后的PHP7的性能:
PHP學習
$ ab -n10000 -c 100 http://inf-dev-maybach.weibo.com:8000/wordpress/
PHP學習
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking inf-dev-maybach.weibo.com (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests
Server Software: nginx/1.7.12
Server Hostname: inf-dev-maybach.weibo.com
Server Port: 8000
Document Path: /wordpress/
Document Length: 9048 bytes
Concurrency Level: 100
Time taken for tests: 8.391 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 92860000 bytes
HTML transferred: 90480000 bytes
Requests per second: 1191.78 [#/sec] (mean)
Time per request: 83.908 [ms] (mean)
Time per request: 0.839 [ms] (mean, across all concurrent requests)
Transfer rate: 10807.45 [Kbytes/sec] received
PHP學習現在每秒鐘可以處理1191.78個QPS了, 提升是~7%. 還不賴哈(咦, 你不是說10%么? 怎么成7%了? 呵呵, 正如我之前說過, 我們嘗試分析PGO都做了些什么優(yōu)化, 然后把一些通用的優(yōu)化手工Apply到PHP7中. 所以也就是說, 那~3%的比較通用的優(yōu)化已經包括到了PHP7里面了, 當然這個工作還在繼續(xù)).
PHP學習于是就這么簡單, 大家可以用本身的產品的經典場景來訓練GCC, 簡單幾步, 獲得提升, 何樂而不為呢
維易PHP培訓學院每天發(fā)布《PHP學習:使用Huagepage和PGO來提升PHP7的執(zhí)行性能》等實戰(zhàn)技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培養(yǎng)人才。
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/8337.html