协程切换开销测试

前言

为了方便其他项目使用协程,最近从Boost中把协程库移植出来,单独分成一个项目。这个协程库没有任何依赖,而且简洁高性能。

函数

1
2
3
4
5
// 切换协程
intptr_t vic_swap_context(vic_context_t *from, vic_context_t to, intptr_t arg, bool preserve_fpu);

// 初始化协程
vic_context_t vic_make_context(void *sp, size_t size, vic_context_entry_t entry);

性能

下面是一份协程切换性能的测试代码,也算是一个使用协程的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
#include <stdlib.h>

#include <vic/context.h>

static const size_t k_stacksize = 1024 * 64;

vic_context_t g_main_fiber = invalid_vic_context;
vic_context_t g_child_fiber = invalid_vic_context;

void child_entry(intptr_t argv) {
while (true) {
vic_swap_context(&g_child_fiber, g_main_fiber, (intptr_t)0, false);
}
}

int32_t main(int32_t argc, char *argv[]) {
unsigned long count = 10000;
if (argc > 1) {
count = strtoul(argv[1], NULL, 10);
}
void *p = malloc(k_stacksize);
void *sp = (char *)p + k_stacksize;
g_child_fiber = vic_make_context(sp, k_stacksize, child_entry);

unsigned long i;
for (i = 0; i < count; ++i) {
vic_swap_context(&g_main_fiber, g_child_fiber, (intptr_t)0, false);
}
free(p);
return 0;
}

运行结果:

1
2
3
4
5
$ time ./bin/context_benchmark 1000000000

real 0m5.102s
user 0m5.100s
sys 0m0.000s

算下来,平均每次切换的消耗大概5.1纳秒。这样在实际应用中,协程切换带来的开销几乎可以忽略不计。

附件

协程库和示例代码已开源,代码地址

文章目录
  1. 1. 前言
  2. 2. 函数
  3. 3. 性能
  4. 4. 附件