github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/prepare/16cacheline/disruptor_exp/main.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/smartystreets/go-disruptor"
     6  	"runtime"
     7  	"strconv"
     8  	"strings"
     9  	"time"
    10  )
    11  
    12  const (
    13  	BufferSize   = 1024 * 64
    14  	BufferMask   = BufferSize - 1
    15  	Iterations   = 10
    16  	Reservations = 16
    17  )
    18  
    19  var (
    20  	ring = [BufferSize]int64{}
    21  )
    22  
    23  type SampleConsumer struct {
    24  	id int
    25  }
    26  
    27  func (s SampleConsumer) Consume(lower, upper int64) {
    28  	gid := GoID()
    29  	for ; lower <= upper; lower++ {
    30  		message := ring[lower&BufferMask]
    31  		fmt.Printf("goid:%d consumeId:%d msg:%d \n", gid, s.id, message)
    32  	}
    33  }
    34  
    35  func GoID() int {
    36  	var buf [64]byte
    37  	n := runtime.Stack(buf[:], false)
    38  	idField := strings.Fields(strings.TrimPrefix(string(buf[:n]), "goroutine "))[0]
    39  	id, err := strconv.Atoi(idField)
    40  	if err != nil {
    41  		panic(fmt.Sprintf("cannot get goroutine id: %v", err))
    42  	}
    43  	return id
    44  }
    45  
    46  func main() {
    47  	n := runtime.NumCPU()
    48  	runtime.GOMAXPROCS(n)
    49  
    50  	controller := disruptor.Configure(BufferSize).WithConsumerGroup(SampleConsumer{1}, SampleConsumer{2}).Build()
    51  
    52  	controller.Start()
    53  
    54  	started := time.Now()
    55  	publish(controller.Writer())
    56  	finished := time.Now()
    57  	select {}
    58  	//controller.Stop()
    59  	fmt.Println(Iterations, finished.Sub(started))
    60  }
    61  
    62  func publish(writer *disruptor.Writer) {
    63  	sequence := disruptor.InitialSequenceValue
    64  	for i := 0; i < Iterations; i++ {
    65  		sequence = writer.Reserve(1) // java api中的next
    66  		ring[sequence&BufferMask] = int64(i)
    67  		writer.Commit(sequence, sequence)
    68  	}
    69  
    70  }
    71  
    72  // func publish(writer *disruptor.Writer) {
    73  // 	sequence := disruptor.InitialSequenceValue
    74  // 	for sequence <= Iterations {
    75  // 		sequence += Reservations // only an advantage at smaller reservations, e.g. 1-4?
    76  // 		writer.Await(sequence)
    77  // 		for lower := sequence - Reservations + 1; lower <= sequence; lower++ {
    78  // 			ring[lower&BufferMask] = lower
    79  // 		}
    80  // 		writer.Commit(sequence-Reservations+1, sequence)
    81  // 	}
    82  // }