github.com/geph-official/geph2@v0.22.6-0.20210211030601-f527cb59b0df/libs/kcp-go/kcp_bic.go (about) 1 package kcp 2 3 import ( 4 "log" 5 "math" 6 "time" 7 ) 8 9 const bicMultiplier = 1 10 11 func (kcp *KCP) cubic_onloss(lost []uint32) { 12 kcp.wmax = kcp.cwnd 13 kcp.cwnd *= (2 - cubicB) / 2 14 kcp.lastLoss = time.Now() 15 if kcp.cwnd < 32 { 16 kcp.cwnd = 32 17 } 18 log.Println("wmax at", int(kcp.cwnd)) 19 } 20 21 func (kcp *KCP) bic_onloss(lost []uint32) { 22 maxRun := 1 23 currRun := 0 24 lastSeen := uint32(0) 25 for _, v := range lost { 26 if v == lastSeen+1 { 27 currRun++ 28 if maxRun < currRun { 29 maxRun = currRun 30 } 31 } else { 32 currRun = 0 33 } 34 lastSeen = v 35 } 36 // log.Println("lost with maxRun", maxRun) 37 // if maxRun < int(kcp.cwnd/20) || maxRun < 10 { 38 // return 39 // } 40 beta := 0.05 / bicMultiplier 41 if kcp.cwnd < kcp.wmax { 42 kcp.wmax = kcp.cwnd * (2.0 - beta) / 2.0 43 } else { 44 kcp.wmax = kcp.cwnd 45 } 46 kcp.cwnd = kcp.cwnd * (1.0 - beta) 47 mincwnd := kcp.bdp() / float64(kcp.mss) 48 if kcp.cwnd < mincwnd { 49 kcp.cwnd = mincwnd 50 } 51 if kcp.cwnd < 32 { 52 kcp.cwnd = 32 53 } 54 } 55 56 const ( 57 cubicC = 100 58 cubicB = 0.5 59 ) 60 61 func (kcp *KCP) cubic_onack(acks int32) { 62 if doLogging { 63 log.Printf("CUBIC cwnd=%v // t=%.2f%%", int(kcp.cwnd), 64 100*float64(kcp.retrans)/float64(kcp.trans)) 65 } 66 for i := int32(0); i < acks; i++ { 67 t := time.Since(kcp.lastLoss).Seconds() 68 K := math.Pow(kcp.wmax*cubicB/cubicC, 1.0/3.0) 69 kcp.cwnd = math.Min(cubicC*math.Pow(t-K, 3)+kcp.wmax, kcp.cwnd+1) 70 } 71 } 72 73 func (kcp *KCP) bic_onack(acks int32) { 74 if doLogging { 75 log.Printf("BIC cwnd=%v // t=%.2f%%", int(kcp.cwnd), 76 100*float64(kcp.retrans)/float64(kcp.trans)) 77 } 78 79 // // TCP BIC 80 for i := 0; i < int(acks*bicMultiplier); i++ { 81 var bicinc float64 82 if kcp.cwnd < kcp.wmax { 83 bicinc = (kcp.wmax - kcp.cwnd) / 2 84 } else { 85 bicinc = kcp.cwnd - kcp.wmax 86 } 87 if bicinc <= 1 { 88 bicinc = 1 89 } else { 90 if bicinc > 128 { 91 bicinc = 128 92 } 93 } 94 kcp.cwnd += bicinc / kcp.cwnd 95 if uint32(kcp.cwnd) > kcp.rmt_wnd { 96 kcp.cwnd = float64(kcp.rmt_wnd) 97 } 98 } 99 // if doLogging { 100 // log.Printf("BIC cwnd %.2f => %.2f [%.2f %%]", kcp.cwnd, kcp.wmax, float64(kcp.retrans)/float64(kcp.trans)*100) 101 // } 102 // kcp.cwnd += float64(acks) * kcp.aimd_multiplier() 103 }