go.nanomsg.org/mangos/v3@v3.4.3-0.20240217232803-46464076f1f5/perf/throughput.go (about) 1 // Copyright 2019 The Mangos Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use file except in compliance with the License. 5 // You may obtain a copy of the license at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package main 16 17 import ( 18 "fmt" 19 "log" 20 "time" 21 22 "go.nanomsg.org/mangos/v3/protocol/pair" 23 "go.nanomsg.org/mangos/v3/transport/all" 24 ) 25 26 // ThroughputServer is the server side -- very much equivalent to local_thr in 27 // nanomsg/perf. It does the measurement by counting packets received. 28 func ThroughputServer(addr string, msgSize int, count int) { 29 s, err := pair.NewSocket() 30 if err != nil { 31 log.Fatalf("Failed to make new pair socket: %v", err) 32 } 33 defer func() { 34 _ = s.Close() 35 }() 36 37 all.AddTransports(s) 38 l, err := s.NewListener(addr, nil) 39 if err != nil { 40 log.Fatalf("Failed to make new listener: %v", err) 41 } 42 43 if err = l.Listen(); err != nil { 44 log.Fatalf("Failed to listen: %v", err) 45 } 46 47 msg, err := s.RecvMsg() 48 if err != nil { 49 log.Fatalf("Failed to receive start message: %v", err) 50 } 51 msg.Free() 52 53 start := time.Now() 54 55 for i := 0; i != count; i++ { 56 msg, err := s.RecvMsg() 57 if err != nil { 58 log.Fatalf("Failed to recv: %v", err) 59 } 60 if len(msg.Body) != msgSize { 61 log.Fatalf("Received wrong message size: %d != %d", len(msg.Body), msgSize) 62 } 63 // return to cache to avoid GC 64 msg.Free() 65 } 66 67 finish := time.Now() 68 69 delta := finish.Sub(start) 70 deltasec := float64(delta) / float64(time.Second) 71 msgpersec := float64(count) / deltasec 72 mbps := (float64((count)*8*msgSize) / deltasec) / 1000000.0 73 fmt.Printf("message size: %d [B]\n", msgSize) 74 fmt.Printf("message count: %d\n", count) 75 fmt.Printf("throughput: %d [msg/s]\n", uint64(msgpersec)) 76 fmt.Printf("throughput: %.3f [Mb/s]\n", mbps) 77 } 78 79 // ThroughputClient is the client side of the latency test. It simply sends 80 // the requested number of packets of given size to the server. It corresponds 81 // to remote_thr. 82 func ThroughputClient(addr string, msgSize int, count int) { 83 s, err := pair.NewSocket() 84 if err != nil { 85 log.Fatalf("Failed to make new pair socket: %v", err) 86 } 87 defer func() { 88 _ = s.Close() 89 }() 90 91 all.AddTransports(s) 92 d, err := s.NewDialer(addr, nil) 93 if err != nil { 94 log.Fatalf("Failed to make new dialer: %v", err) 95 } 96 97 err = d.Dial() 98 if err != nil { 99 log.Fatalf("Failed to dial: %v", err) 100 } 101 102 // 100 milliseconds to give TCP a chance to establish 103 time.Sleep(time.Millisecond * 100) 104 105 body := make([]byte, msgSize) 106 for i := 0; i < msgSize; i++ { 107 body[i] = 111 108 } 109 110 // send the start message 111 _ = s.Send([]byte{}) 112 113 for i := 0; i < count; i++ { 114 if err = s.Send(body); err != nil { 115 log.Fatalf("Failed SendMsg: %v", err) 116 } 117 } 118 }