improve performance & optimize fast-ack
This commit is contained in:
parent
aec1aa6ef1
commit
3806c95073
45
ikcp.c
45
ikcp.c
@ -541,15 +541,14 @@ static void ikcp_parse_ack(ikcpcb *kcp, IUINT32 sn)
|
|||||||
kcp->nsnd_buf--;
|
kcp->nsnd_buf--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
if (_itimediff(sn, seg->sn) < 0) {
|
||||||
seg->fastack++;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ikcp_parse_una(ikcpcb *kcp, IUINT32 una)
|
static void ikcp_parse_una(ikcpcb *kcp, IUINT32 una)
|
||||||
{
|
{
|
||||||
#if 1
|
|
||||||
struct IQUEUEHEAD *p, *next;
|
struct IQUEUEHEAD *p, *next;
|
||||||
for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = next) {
|
for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = next) {
|
||||||
IKCPSEG *seg = iqueue_entry(p, IKCPSEG, node);
|
IKCPSEG *seg = iqueue_entry(p, IKCPSEG, node);
|
||||||
@ -562,7 +561,25 @@ static void ikcp_parse_una(ikcpcb *kcp, IUINT32 una)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
|
|
||||||
|
static void ikcp_parse_fastack(ikcpcb *kcp, IUINT32 sn)
|
||||||
|
{
|
||||||
|
struct IQUEUEHEAD *p, *next;
|
||||||
|
|
||||||
|
if (_itimediff(sn, kcp->snd_una) < 0 || _itimediff(sn, kcp->snd_nxt) >= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = next) {
|
||||||
|
IKCPSEG *seg = iqueue_entry(p, IKCPSEG, node);
|
||||||
|
next = p->next;
|
||||||
|
if (_itimediff(sn, seg->sn) < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (sn != seg->sn) {
|
||||||
|
seg->fastack++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -684,6 +701,8 @@ void ikcp_parse_data(ikcpcb *kcp, IKCPSEG *newseg)
|
|||||||
int ikcp_input(ikcpcb *kcp, const char *data, long size)
|
int ikcp_input(ikcpcb *kcp, const char *data, long size)
|
||||||
{
|
{
|
||||||
IUINT32 una = kcp->snd_una;
|
IUINT32 una = kcp->snd_una;
|
||||||
|
IUINT32 maxack = 0;
|
||||||
|
int flag = 0;
|
||||||
|
|
||||||
if (ikcp_canlog(kcp, IKCP_LOG_INPUT)) {
|
if (ikcp_canlog(kcp, IKCP_LOG_INPUT)) {
|
||||||
ikcp_log(kcp, IKCP_LOG_INPUT, "[RI] %d bytes", size);
|
ikcp_log(kcp, IKCP_LOG_INPUT, "[RI] %d bytes", size);
|
||||||
@ -728,6 +747,14 @@ int ikcp_input(ikcpcb *kcp, const char *data, long size)
|
|||||||
}
|
}
|
||||||
ikcp_parse_ack(kcp, sn);
|
ikcp_parse_ack(kcp, sn);
|
||||||
ikcp_shrink_buf(kcp);
|
ikcp_shrink_buf(kcp);
|
||||||
|
if (flag == 0) {
|
||||||
|
flag = 1;
|
||||||
|
maxack = sn;
|
||||||
|
} else {
|
||||||
|
if (_itimediff(sn, maxack) > 0) {
|
||||||
|
maxack = sn;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (ikcp_canlog(kcp, IKCP_LOG_IN_ACK)) {
|
if (ikcp_canlog(kcp, IKCP_LOG_IN_ACK)) {
|
||||||
ikcp_log(kcp, IKCP_LOG_IN_DATA,
|
ikcp_log(kcp, IKCP_LOG_IN_DATA,
|
||||||
"input ack: sn=%lu rtt=%ld rto=%ld", sn,
|
"input ack: sn=%lu rtt=%ld rto=%ld", sn,
|
||||||
@ -784,6 +811,10 @@ int ikcp_input(ikcpcb *kcp, const char *data, long size)
|
|||||||
size -= len;
|
size -= len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flag != 0) {
|
||||||
|
ikcp_parse_fastack(kcp, maxack);
|
||||||
|
}
|
||||||
|
|
||||||
if (_itimediff(kcp->snd_una, una) > 0) {
|
if (_itimediff(kcp->snd_una, una) > 0) {
|
||||||
if (kcp->cwnd < kcp->rmt_wnd) {
|
if (kcp->cwnd < kcp->rmt_wnd) {
|
||||||
IUINT32 mss = kcp->mss;
|
IUINT32 mss = kcp->mss;
|
||||||
@ -865,7 +896,7 @@ void ikcp_flush(ikcpcb *kcp)
|
|||||||
count = kcp->ackcount;
|
count = kcp->ackcount;
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
size = (int)(ptr - buffer);
|
size = (int)(ptr - buffer);
|
||||||
if (size + IKCP_OVERHEAD > (int)kcp->mtu) {
|
if (size + (int)IKCP_OVERHEAD > (int)kcp->mtu) {
|
||||||
ikcp_output(kcp, buffer, size);
|
ikcp_output(kcp, buffer, size);
|
||||||
ptr = buffer;
|
ptr = buffer;
|
||||||
}
|
}
|
||||||
@ -901,7 +932,7 @@ void ikcp_flush(ikcpcb *kcp)
|
|||||||
if (kcp->probe & IKCP_ASK_SEND) {
|
if (kcp->probe & IKCP_ASK_SEND) {
|
||||||
seg.cmd = IKCP_CMD_WASK;
|
seg.cmd = IKCP_CMD_WASK;
|
||||||
size = (int)(ptr - buffer);
|
size = (int)(ptr - buffer);
|
||||||
if (size + IKCP_OVERHEAD > (int)kcp->mtu) {
|
if (size + (int)IKCP_OVERHEAD > (int)kcp->mtu) {
|
||||||
ikcp_output(kcp, buffer, size);
|
ikcp_output(kcp, buffer, size);
|
||||||
ptr = buffer;
|
ptr = buffer;
|
||||||
}
|
}
|
||||||
@ -912,7 +943,7 @@ void ikcp_flush(ikcpcb *kcp)
|
|||||||
if (kcp->probe & IKCP_ASK_TELL) {
|
if (kcp->probe & IKCP_ASK_TELL) {
|
||||||
seg.cmd = IKCP_CMD_WINS;
|
seg.cmd = IKCP_CMD_WINS;
|
||||||
size = (int)(ptr - buffer);
|
size = (int)(ptr - buffer);
|
||||||
if (size + IKCP_OVERHEAD > (int)kcp->mtu) {
|
if (size + (int)IKCP_OVERHEAD > (int)kcp->mtu) {
|
||||||
ikcp_output(kcp, buffer, size);
|
ikcp_output(kcp, buffer, size);
|
||||||
ptr = buffer;
|
ptr = buffer;
|
||||||
}
|
}
|
||||||
|
12
test.cpp
12
test.cpp
@ -71,6 +71,8 @@ void test(int mode)
|
|||||||
// 第五个参数 为是否禁用常规流控,这里禁止
|
// 第五个参数 为是否禁用常规流控,这里禁止
|
||||||
ikcp_nodelay(kcp1, 1, 10, 2, 1);
|
ikcp_nodelay(kcp1, 1, 10, 2, 1);
|
||||||
ikcp_nodelay(kcp2, 1, 10, 2, 1);
|
ikcp_nodelay(kcp2, 1, 10, 2, 1);
|
||||||
|
kcp1->rx_minrto = 10;
|
||||||
|
kcp1->fastresend = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -87,8 +89,8 @@ void test(int mode)
|
|||||||
|
|
||||||
// 每隔 20ms,kcp1发送数据
|
// 每隔 20ms,kcp1发送数据
|
||||||
for (; current >= slap; slap += 20) {
|
for (; current >= slap; slap += 20) {
|
||||||
*(IUINT32*)(buffer + 0) = index++;
|
((IUINT32*)buffer)[0] = index++;
|
||||||
*(IUINT32*)(buffer + 4) = current;
|
((IUINT32*)buffer)[1] = current;
|
||||||
|
|
||||||
// 发送上层协议包
|
// 发送上层协议包
|
||||||
ikcp_send(kcp1, buffer, 8);
|
ikcp_send(kcp1, buffer, 8);
|
||||||
@ -151,15 +153,15 @@ void test(int mode)
|
|||||||
|
|
||||||
const char *names[3] = { "default", "normal", "fast" };
|
const char *names[3] = { "default", "normal", "fast" };
|
||||||
printf("%s mode result (%dms):\n", names[mode], (int)ts1);
|
printf("%s mode result (%dms):\n", names[mode], (int)ts1);
|
||||||
printf("avgrtt=%d maxrtt=%d\n", (int)(sumrtt / count), maxrtt);
|
printf("avgrtt=%d maxrtt=%d tx=%d\n", (int)(sumrtt / count), (int)maxrtt, (int)vnet->tx1);
|
||||||
printf("press enter to next ...\n");
|
printf("press enter to next ...\n");
|
||||||
char ch; scanf("%c", &ch);
|
char ch; scanf("%c", &ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
test(0); // 默认模式,类似 TCP:正常模式,无快速重传,常规流控
|
//test(0); // 默认模式,类似 TCP:正常模式,无快速重传,常规流控
|
||||||
test(1); // 普通模式,关闭流控等
|
//test(1); // 普通模式,关闭流控等
|
||||||
test(2); // 快速模式,所有开关都打开,且关闭流控
|
test(2); // 快速模式,所有开关都打开,且关闭流控
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
8
test.h
8
test.h
@ -146,6 +146,7 @@ protected:
|
|||||||
class LatencySimulator
|
class LatencySimulator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual ~LatencySimulator() {
|
virtual ~LatencySimulator() {
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
@ -160,6 +161,7 @@ public:
|
|||||||
this->rttmin = rttmin / 2;
|
this->rttmin = rttmin / 2;
|
||||||
this->rttmax = rttmax / 2;
|
this->rttmax = rttmax / 2;
|
||||||
this->nmax = nmax;
|
this->nmax = nmax;
|
||||||
|
tx1 = tx2 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清除数据
|
// 清除数据
|
||||||
@ -179,9 +181,11 @@ public:
|
|||||||
// peer - 端点0/1,从0发送,从1接收;从1发送从0接收
|
// peer - 端点0/1,从0发送,从1接收;从1发送从0接收
|
||||||
void send(int peer, const void *data, int size) {
|
void send(int peer, const void *data, int size) {
|
||||||
if (peer == 0) {
|
if (peer == 0) {
|
||||||
|
tx1++;
|
||||||
if (r12.random() < lostrate) return;
|
if (r12.random() < lostrate) return;
|
||||||
if ((int)p12.size() >= nmax) return;
|
if ((int)p12.size() >= nmax) return;
|
||||||
} else {
|
} else {
|
||||||
|
tx2++;
|
||||||
if (r21.random() < lostrate) return;
|
if (r21.random() < lostrate) return;
|
||||||
if ((int)p21.size() >= nmax) return;
|
if ((int)p21.size() >= nmax) return;
|
||||||
}
|
}
|
||||||
@ -222,6 +226,10 @@ public:
|
|||||||
return maxsize;
|
return maxsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
int tx1;
|
||||||
|
int tx2;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
IUINT32 current;
|
IUINT32 current;
|
||||||
int lostrate;
|
int lostrate;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user