If you just print the final value of V in both cases you will see: On my iMac:

channels: 215606060
mutex: 651606060

Or the mutex has 3x greater throughput. How the Go routines are scheduled is OS 
dependent - the OSX code uses the same mechanism in both cases.

You have to remember that that the benchmark harness times the cost of 
operation when it runs, but it doesn’t always run the same number of 
invocations - it is based on the the scheduling of the Go routines, and the 
desired length of the test time.

goos: darwin
goarch: amd64
BenchmarkChanWrite/goroutines-4800-8             3000000               638 ns/op
BenchmarkChanWrite/goroutines-4880-8             2000000               636 ns/op
BenchmarkChanWrite/goroutines-4960-8             3000000               602 ns/op
BenchmarkChanWrite/goroutines-5040-8             2000000               632 ns/op
BenchmarkChanWrite/goroutines-5120-8             2000000               591 ns/op
BenchmarkChanWrite/goroutines-5200-8             3000000               634 ns/op
BenchmarkChanWrite/goroutines-5280-8             3000000               632 ns/op
BenchmarkChanWrite/goroutines-5360-8             3000000               581 ns/op
BenchmarkChanWrite/goroutines-5440-8             3000000               584 ns/op
BenchmarkChanWrite/goroutines-5520-8             3000000               582 ns/op
BenchmarkChanWrite/goroutines-5600-8             3000000               601 ns/op
BenchmarkChanWrite/goroutines-5680-8             3000000               609 ns/op
BenchmarkChanWrite/goroutines-5760-8             3000000               597 ns/op
BenchmarkChanWrite/goroutines-5840-8             3000000               674 ns/op
BenchmarkChanWrite/goroutines-5920-8             3000000               597 ns/op
BenchmarkChanWrite/goroutines-6000-8             3000000               601 ns/op
BenchmarkChanWrite/goroutines-6080-8             2000000               616 ns/op
BenchmarkChanWrite/goroutines-6160-8             3000000               603 ns/op
BenchmarkChanWrite/goroutines-6240-8             2000000               624 ns/op
BenchmarkChanWrite/goroutines-6320-8             3000000               603 ns/op
BenchmarkChanWrite/goroutines-6400-8             3000000               602 ns/op
BenchmarkChanWrite/goroutines-6480-8             2000000               616 ns/op
BenchmarkChanWrite/goroutines-6560-8             2000000               611 ns/op
BenchmarkChanWrite/goroutines-6640-8             3000000               603 ns/op
BenchmarkChanWrite/goroutines-6720-8             2000000               621 ns/op
BenchmarkChanWrite/goroutines-6800-8             3000000               636 ns/op
BenchmarkChanWrite/goroutines-6880-8             2000000               655 ns/op
BenchmarkChanWrite/goroutines-6960-8             3000000               605 ns/op
BenchmarkChanWrite/goroutines-7040-8             3000000               606 ns/op
BenchmarkChanWrite/goroutines-7120-8             2000000               639 ns/op
BenchmarkChanWrite/goroutines-7200-8             3000000               608 ns/op
BenchmarkChanWrite/goroutines-7280-8             3000000               617 ns/op
BenchmarkChanWrite/goroutines-7360-8             3000000               594 ns/op
BenchmarkChanWrite/goroutines-7440-8             3000000               596 ns/op
BenchmarkChanWrite/goroutines-7520-8             2000000               599 ns/op
BenchmarkChanWrite/goroutines-7600-8             2000000               610 ns/op
BenchmarkChanWrite/goroutines-7680-8             3000000               597 ns/op
BenchmarkChanWrite/goroutines-7760-8             2000000               608 ns/op
BenchmarkChanWrite/goroutines-7840-8             3000000               592 ns/op
BenchmarkChanWrite/goroutines-7920-8             3000000               611 ns/op
BenchmarkChanWrite/goroutines-8000-8             2000000               618 ns/op
BenchmarkChanWrite/goroutines-8080-8             3000000               612 ns/op
BenchmarkChanWrite/goroutines-8160-8             2000000               609 ns/op
BenchmarkChanWrite/goroutines-8240-8             3000000               594 ns/op
BenchmarkChanWrite/goroutines-8320-8             3000000               629 ns/op
BenchmarkChanWrite/goroutines-8400-8             2000000               624 ns/op
BenchmarkChanWrite/goroutines-8480-8             2000000               606 ns/op
BenchmarkChanWrite/goroutines-8560-8             2000000               635 ns/op
BenchmarkChanWrite/goroutines-8640-8             2000000               603 ns/op
BenchmarkChanWrite/goroutines-8720-8             3000000               625 ns/op
BenchmarkChanWrite/goroutines-8800-8             2000000               632 ns/op
BenchmarkChanWrite/goroutines-8880-8             2000000               602 ns/op
BenchmarkChanWrite/goroutines-8960-8             3000000               632 ns/op
BenchmarkChanWrite/goroutines-9040-8             2000000               602 ns/op
BenchmarkChanWrite/goroutines-9120-8             3000000               625 ns/op
BenchmarkChanWrite/goroutines-9200-8             3000000               657 ns/op
BenchmarkChanWrite/goroutines-9280-8             3000000               681 ns/op
BenchmarkChanWrite/goroutines-9360-8             2000000               630 ns/op
BenchmarkChanWrite/goroutines-9440-8             2000000               623 ns/op
BenchmarkChanWrite/goroutines-9520-8             2000000               613 ns/op
215606060
BenchmarkMutexWrite/goroutines-4800-8           10000000               634 ns/op
BenchmarkMutexWrite/goroutines-4880-8           20000000               635 ns/op
BenchmarkMutexWrite/goroutines-4960-8           20000000               645 ns/op
BenchmarkMutexWrite/goroutines-5040-8           20000000               665 ns/op
BenchmarkMutexWrite/goroutines-5120-8           20000000               627 ns/op
BenchmarkMutexWrite/goroutines-5200-8           20000000               721 ns/op
BenchmarkMutexWrite/goroutines-5280-8           20000000               697 ns/op
BenchmarkMutexWrite/goroutines-5360-8           20000000               697 ns/op
BenchmarkMutexWrite/goroutines-5440-8            5000000               628 ns/op
BenchmarkMutexWrite/goroutines-5520-8           10000000               647 ns/op
BenchmarkMutexWrite/goroutines-5600-8            3000000               528 ns/op
BenchmarkMutexWrite/goroutines-5680-8           10000000               656 ns/op
BenchmarkMutexWrite/goroutines-5760-8           10000000               649 ns/op
BenchmarkMutexWrite/goroutines-5840-8           20000000               721 ns/op
BenchmarkMutexWrite/goroutines-5920-8           10000000               666 ns/op
BenchmarkMutexWrite/goroutines-6000-8           10000000               655 ns/op
BenchmarkMutexWrite/goroutines-6080-8           20000000               719 ns/op
BenchmarkMutexWrite/goroutines-6160-8           10000000               730 ns/op
BenchmarkMutexWrite/goroutines-6240-8            5000000               524 ns/op
BenchmarkMutexWrite/goroutines-6320-8            5000000               645 ns/op
BenchmarkMutexWrite/goroutines-6400-8            5000000               753 ns/op
BenchmarkMutexWrite/goroutines-6480-8           10000000               755 ns/op
BenchmarkMutexWrite/goroutines-6560-8           10000000               697 ns/op
BenchmarkMutexWrite/goroutines-6640-8           10000000               682 ns/op
BenchmarkMutexWrite/goroutines-6720-8           10000000               698 ns/op
BenchmarkMutexWrite/goroutines-6800-8           10000000               661 ns/op
BenchmarkMutexWrite/goroutines-6880-8            5000000               609 ns/op
BenchmarkMutexWrite/goroutines-6960-8           10000000               689 ns/op
BenchmarkMutexWrite/goroutines-7040-8            5000000               656 ns/op
BenchmarkMutexWrite/goroutines-7120-8           10000000               682 ns/op
BenchmarkMutexWrite/goroutines-7200-8            5000000               578 ns/op
BenchmarkMutexWrite/goroutines-7280-8            3000000               607 ns/op
BenchmarkMutexWrite/goroutines-7360-8            5000000               544 ns/op
BenchmarkMutexWrite/goroutines-7440-8            5000000               589 ns/op
BenchmarkMutexWrite/goroutines-7520-8           20000000               692 ns/op
BenchmarkMutexWrite/goroutines-7600-8            5000000               673 ns/op
BenchmarkMutexWrite/goroutines-7680-8            5000000               618 ns/op
BenchmarkMutexWrite/goroutines-7760-8            5000000               667 ns/op
BenchmarkMutexWrite/goroutines-7840-8           10000000               730 ns/op
BenchmarkMutexWrite/goroutines-7920-8            5000000               628 ns/op
BenchmarkMutexWrite/goroutines-8000-8           10000000               758 ns/op
BenchmarkMutexWrite/goroutines-8080-8           10000000               634 ns/op
BenchmarkMutexWrite/goroutines-8160-8            5000000               640 ns/op
BenchmarkMutexWrite/goroutines-8240-8            5000000               622 ns/op
BenchmarkMutexWrite/goroutines-8320-8           10000000               680 ns/op
BenchmarkMutexWrite/goroutines-8400-8           10000000               687 ns/op
BenchmarkMutexWrite/goroutines-8480-8            5000000               575 ns/op
BenchmarkMutexWrite/goroutines-8560-8           10000000               693 ns/op
BenchmarkMutexWrite/goroutines-8640-8           10000000               657 ns/op
BenchmarkMutexWrite/goroutines-8720-8           10000000               716 ns/op
BenchmarkMutexWrite/goroutines-8800-8            5000000               513 ns/op
BenchmarkMutexWrite/goroutines-8880-8            5000000               543 ns/op
BenchmarkMutexWrite/goroutines-8960-8            5000000               811 ns/op
BenchmarkMutexWrite/goroutines-9040-8           10000000               741 ns/op
BenchmarkMutexWrite/goroutines-9120-8            5000000               683 ns/op
BenchmarkMutexWrite/goroutines-9200-8            5000000               666 ns/op
BenchmarkMutexWrite/goroutines-9280-8           30000000               746 ns/op
BenchmarkMutexWrite/goroutines-9360-8            5000000               638 ns/op
BenchmarkMutexWrite/goroutines-9440-8            5000000               658 ns/op
BenchmarkMutexWrite/goroutines-9520-8           10000000               688 ns/op
651606060
PASS

> On Aug 20, 2019, at 3:33 AM, changkun <euryugas...@gmail.com> wrote:
> 
> Hi Robert,
> 
> Thanks for your explanation. But how could I "logged the number of operations 
> done per Go routine", which particular debug settings you referring to?
> It is reasonable that sync.Mutex rely on runtime scheduler but channels do 
> not. However, it is unclear why a significant performance drop appears. Is it 
> possible to determine when the performance will appear?
> 
> Best,
> Changkun
> 
> On Monday, August 19, 2019 at 10:27:19 PM UTC+2, Robert Engels wrote:
> I think you'll find the reason that the Mutex uses the Go scheduler. The chan 
> is controlled by a 'mutex' which eventually defers to the OS futex - and the 
> OS futex is probably more efficient at scheduling in the face of large 
> contention - although you would think it should be the other way around.
> 
> I am guessing that if you logged the number of operations done per Go 
> routine, you will see that the Mutex version is very fair, and the chan/futex 
> version is unfair - meaning many are starved.
> 
> -----Original Message----- 
> From: changkun 
> Sent: Aug 19, 2019 12:50 PM 
> To: golang-nuts 
> Subject: [go-nuts] sync.Mutex encounter large performance drop when goroutine 
> contention more than 3400 
> 
> I am comparing the performance regarding sync.Mutex and Go channels. Here is 
> my benchmark: https://play.golang.org/p/zLjVtsSx9gd 
> <https://play.golang.org/p/zLjVtsSx9gd>
> 
> The performance comparison visualization is as follows:
> 
> 
> 
> What are the reasons that 
> 
> 1. sync.Mutex encounter a large performance drop when the number of 
> goroutines goes higher than roughly 3400?
> 2. Go channels are pretty stable but slower than sync.Mutex before?
> 
> 
> 
> Raw bench data by benchstat (go test -bench=. -count=5):
> 
> MutexWrite/goroutines-2400-8  48.6ns ± 1%
> MutexWrite/goroutines-2480-8  49.1ns ± 0%
> MutexWrite/goroutines-2560-8  49.7ns ± 1%
> MutexWrite/goroutines-2640-8  50.5ns ± 3%
> MutexWrite/goroutines-2720-8  50.9ns ± 2%
> MutexWrite/goroutines-2800-8  51.8ns ± 3%
> MutexWrite/goroutines-2880-8  52.5ns ± 2%
> MutexWrite/goroutines-2960-8  54.1ns ± 4%
> MutexWrite/goroutines-3040-8  54.5ns ± 2%
> MutexWrite/goroutines-3120-8  56.1ns ± 3%
> MutexWrite/goroutines-3200-8  63.2ns ± 5%
> MutexWrite/goroutines-3280-8  77.5ns ± 6%
> MutexWrite/goroutines-3360-8   141ns ± 6%
> MutexWrite/goroutines-3440-8   239ns ± 8%
> MutexWrite/goroutines-3520-8   248ns ± 3%
> MutexWrite/goroutines-3600-8   254ns ± 2%
> MutexWrite/goroutines-3680-8   256ns ± 1%
> MutexWrite/goroutines-3760-8   261ns ± 2%
> MutexWrite/goroutines-3840-8   266ns ± 3%
> MutexWrite/goroutines-3920-8   276ns ± 3%
> MutexWrite/goroutines-4000-8   278ns ± 3%
> MutexWrite/goroutines-4080-8   286ns ± 5%
> MutexWrite/goroutines-4160-8   293ns ± 4%
> MutexWrite/goroutines-4240-8   295ns ± 2%
> MutexWrite/goroutines-4320-8   280ns ± 8%
> MutexWrite/goroutines-4400-8   294ns ± 9%
> MutexWrite/goroutines-4480-8   285ns ±10%
> MutexWrite/goroutines-4560-8   290ns ± 8%
> MutexWrite/goroutines-4640-8   271ns ± 3%
> MutexWrite/goroutines-4720-8   271ns ± 4%
> 
> ChanWrite/goroutines-2400-8  158ns ± 3%
> ChanWrite/goroutines-2480-8  159ns ± 2%
> ChanWrite/goroutines-2560-8  161ns ± 2%
> ChanWrite/goroutines-2640-8  161ns ± 1%
> ChanWrite/goroutines-2720-8  163ns ± 1%
> ChanWrite/goroutines-2800-8  166ns ± 3%
> ChanWrite/goroutines-2880-8  168ns ± 1%
> ChanWrite/goroutines-2960-8  176ns ± 4%
> ChanWrite/goroutines-3040-8  176ns ± 2%
> ChanWrite/goroutines-3120-8  180ns ± 1%
> ChanWrite/goroutines-3200-8  180ns ± 1%
> ChanWrite/goroutines-3280-8  181ns ± 2%
> ChanWrite/goroutines-3360-8  183ns ± 2%
> ChanWrite/goroutines-3440-8  188ns ± 3%
> ChanWrite/goroutines-3520-8  190ns ± 2%
> ChanWrite/goroutines-3600-8  193ns ± 2%
> ChanWrite/goroutines-3680-8  196ns ± 3%
> ChanWrite/goroutines-3760-8  199ns ± 2%
> ChanWrite/goroutines-3840-8  206ns ± 2%
> ChanWrite/goroutines-3920-8  209ns ± 2%
> ChanWrite/goroutines-4000-8  206ns ± 2%
> ChanWrite/goroutines-4080-8  209ns ± 2%
> ChanWrite/goroutines-4160-8  208ns ± 2%
> ChanWrite/goroutines-4240-8  209ns ± 3%
> ChanWrite/goroutines-4320-8  213ns ± 2%
> ChanWrite/goroutines-4400-8  209ns ± 2%
> ChanWrite/goroutines-4480-8  211ns ± 1%
> ChanWrite/goroutines-4560-8  213ns ± 2%
> ChanWrite/goroutines-4640-8  215ns ± 1%
> ChanWrite/goroutines-4720-8  218ns ± 3%
> 
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golan...@ <>googlegroups.com <http://googlegroups.com/>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/3275fb21-dfbd-411d-be42-683386e7ebe2%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/golang-nuts/3275fb21-dfbd-411d-be42-683386e7ebe2%40googlegroups.com?utm_medium=email&utm_source=footer>.
> 
> 
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts+unsubscr...@googlegroups.com 
> <mailto:golang-nuts+unsubscr...@googlegroups.com>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/77b8dfc3-53d2-4fbe-9538-cd070d47cd34%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/golang-nuts/77b8dfc3-53d2-4fbe-9538-cd070d47cd34%40googlegroups.com?utm_medium=email&utm_source=footer>.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/A38F0B8D-1FEE-4C2D-BE98-16B6533469B5%40ix.netcom.com.

Reply via email to