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.