同時發佈在獨立博客。 html
之前一直覺得,在Golang中,針對高併發的狀況,採用多核處理必定效果最優,可是項目實踐證實事實不是這樣的。 git
在Sniper項目中(一個結合了ab和siege優勢的http負載測試工具),原來一直設置cup使用數爲系統cpu總數: github
runtime.GOMAXPROCS(runtime.NumCPU()) golang
在與ab的性能比較中一直有較大差距,GET請求局域網的一個10k大小的文件: apache
如下是ab的性能,併發100,總請求100k,執行時間16.082秒 服務器
Concurrency Level: 100
Time taken for tests: 16.082 seconds
Complete requests: 100000
Failed requests: 0
Write errors: 0
Total transferred: 1035500000 bytes
HTML transferred: 1024000000 bytes
Requests per second: 6218.04 [#/sec] (mean)
Time per request: 16.082 [ms] (mean)
Time per request: 0.161 [ms] (mean, across all concurrent requests)
Transfer rate: 62878.74 [Kbytes/sec] received 併發
接下來採用sniper測試,設置runtime.GOMAXPROCS(runtime.NumCPU()) 框架
Transactions: 100000 hits
Availability: 100.00 %
Elapsed time: 20.82 secs
TotalTransfer: 0.00 MB
HTMLTransfer: 0.00 MB
Transaction rate: 4802.45 trans/sec
Throughput: 0.00 MB/sec
Successful: 100000 hits
Failed: 0 hits
TransactionTime: 0.00021 secs(mean)
ConnectionTime: 0.00010 secs(mean)
RequestTime: 0.00000 secs(mean)
ResponseTime: 0.00011 secs(mean) 高併發
能夠看到測試一樣的服務器,使用所有的cpu,sniper耗時20.82秒。 工具
最後我再設置runtime.GOMAXPROCS(1)
Transactions: 100000 hits
Availability: 100.00 %
Elapsed time: 16.71 secs
TotalTransfer: 0.00 MB
HTMLTransfer: 0.00 MB
Transaction rate: 5985.03 trans/sec
Throughput: 0.00 MB/sec
Successful: 100000 hits
Failed: 0 hits
TransactionTime: 0.00017 secs(mean)
ConnectionTime: 0.00003 secs(mean)
RequestTime: 0.00000 secs(mean)
ResponseTime: 0.00014 secs(mean)
能夠看到,sniper的執行時間降到16.71秒,下降了20%。
沒想到優化了這麼久的性能最後居然經過這樣的辦法前進一大步!
出現這種狀況緣由在哪裏?
目前我也解釋不清楚,可能跟CPU的上下文切換有關,詳細的原理須要再研究。有知道原理緣由的請指教。
update:
一個可能的緣由:在這裏看到
和全部其餘併發框架裏的協程同樣,goroutine裏所謂「無鎖」的優勢只在單線程下有效,若是$GOMAXPROCS > 1而且協程間須要通訊,Go運行庫會負責加鎖保護數據。sniper存在大量的協程間通訊,多是鎖影響了性能。